[英]How to raise an exception from within an 'with' block in python
I'm using sqlalchemy to create a transaction.我正在使用 sqlalchemy 创建事务。 I'm using
with
to take advantage of the auto commit and rollback:我正在使用
with
来利用自动提交和回滚:
with session.begin():
do_stuff()
If an exception is raised, is there anyway to propagate that exception after the auto rollback?如果引发异常,是否在自动回滚后传播该异常?
If any exception is raised during the body of a with
statement, the __exit__
method is immediately called with that exception as an argument.如果在
with
语句的主体期间引发任何异常,则立即调用__exit__
方法,并将该异常作为参数。 It is up to __exit__
to then decide whether the exception has been properly handled (by returning a truthy value) or whether it should be re-raised after __exit__
completes (by returning a non-truthy value).然后由
__exit__
决定是否已正确处理异常(通过返回真实值)或是否应在__exit__
完成后重新引发(通过返回非真实值)。
SessionTransaction.__exit__
only returns None
, which indicates that any exception that may have been raised in the body of the with
statement will be raised again. SessionTransaction.__exit__
只返回None
,这表明在with
语句的主体中可能已经引发的任何异常都将再次引发。
Note that since the "default" return value of any function is None
, the default behavior of __exit__
is to propagate any exceptions.请注意,由于任何 function 的“默认”返回值为
None
,因此__exit__
的默认行为是传播任何异常。 No user-level code is expected to call __exit__
explicitly or look at its return value, so you really have to do out of your way to return a truthy value and suppress an expression.用户级代码不应显式调用
__exit__
或查看其返回值,因此您必须竭尽全力返回真实值并抑制表达式。
Also note the description of the with
statement's semantics:还要注意
with
语句语义的描述:
The following code:
以下代码:
with EXPRESSION as TARGET: SUITE
is semantically equivalent to:
在语义上等价于:
manager = (EXPRESSION) enter = type(manager).__enter__ exit = type(manager).__exit__ value = enter(manager) hit_except = False try: TARGET = value SUITE except: hit_except = True if not exit(manager, *sys.exc_info()): raise finally: if not hit_except: exit(manager, None, None, None)
The __exit__
method is called under one of two mutually exclusive conditions: __exit__
方法在两个互斥条件之一下被调用:
except
clause.except
子句中被调用。 If it returns false, the caught exception is re-raised.finally
block.finally
块中被调用。 hit_except
is ensures that exit
is not called twice if exit
itself raises an exception in the except
block. hit_except
确保如果exit
本身在except
块中引发异常,则不会调用两次exit
。You shouldn't need to do anything special.你不应该做任何特别的事情。
Context managers created using with
are roughly equivalent to:使用
with
创建的上下文管理器大致相当于:
try:
context initialization
do_stuff()
finally:
contact cleanup
Unlike an except:
clause, finally:
doesn't block propagation of the exception.与
except:
子句不同, finally:
不会阻止异常的传播。 It executes the statements and then continues propagation.它执行语句,然后继续传播。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.