假设我有以下代码:
try:
[...]
except:
raise Exception([...])
finally:
[code]
我的问题是:如果try
块中的代码引发了一个被捕获的异常except
,是否[code]
来自finally
执行的子句,因为子句中引发了一个新的异常except
?如果是这样,什么时候执行?在引发新异常之前还是在通过方法堆栈传播新异常之后?
一个例子值一千字,你为什么不试试你写的?
>>> def foo():
>>> try:
>>> print "2 try block"
>>> raise Exception("1")
>>> print "never printed"
>>> except:
>>> print "3 first except block"
>>> raise Exception("2")
>>> finally:
>>> print "4 finally block"
>>> print "end of function"
>>>
>>> try:
>>> print "1 before foo"
>>> foo()
>>> print "never printed too"
>>> except:
>>> print "5 outter except clause"
1 before foo
2 try block
3 first except block
4 finally block
5 outter except clause
在引发新异常之前还是在通过方法堆栈传播新异常之后?
从这个例子中你可以看出,finally 块是在它定义的except 块之后调用的(即在离开try
//块之后),但在到达外部except
/块之前。finally
try
except
这是合乎逻辑的,您希望 finally 在退出try
块时始终被触发,但是您退出它,因此您可以确保在try
语句之外执行代码时您的代码环境是一致的(无论您是释放资源还是重置值,或回滚/提交修改...)。
无论 try 块成功还是由于异常而运行 except 块,都将执行 finally!
即使您的 except 块引发异常,新异常也将由另一个 try catch 处理程序处理,但在执行 finally 块之后,而不是形成递归循环:
try:
try:
[...]
except:
raise Exception([...]) #this is line number xyz
finally:
[code]
except:
[...] #this code will be running after line number xyz