我可以在Python的finally块中获取异常吗?
我在我的脚本里有一个 try
/finally
的结构。请问在 finally
这个部分能不能获取到具体的错误信息呢?
5 个回答
4
其实,其他的回答有点模糊。所以让我来解释一下。你可以在finally块中随时调用sys.exc_info()。不过,它的输出会根据是否真的发生了异常而有所不同。
import sys
def f(i):
try:
if i == 1:
raise Exception
except Exception as e:
print "except -> " + str(sys.exc_info())
finally:
print "finally -> " + str(sys.exc_info())
f(0)
f(1)
>>>
finally -> (None, None, None)
except -> (<type 'exceptions.Exception'>, Exception(), <traceback object at 0x029438F0>)
finally -> (<type 'exceptions.Exception'>, Exception(), <traceback object at 0x029438F0>)
因此,在finally块中,你总是可以知道是否发生了异常,前提是这是一个一级函数。但是,当调用栈的长度超过1时,sys.exc_info()的表现会有所不同,下面的例子就说明了这一点。想了解更多信息,可以参考sys.exc_info()是如何工作的?
import sys
def f(i):
try:
if i == 1:
raise Exception
except Exception as e:
print "except -> " + str(sys.exc_info())
finally:
print "finally -> " + str(sys.exc_info())
def f1(i):
if i == 0:
try:
raise Exception('abc')
except Exception as e:
pass
f(i)
f1(0)
f1(1)
>>>
finally -> (<type 'exceptions.Exception'>, Exception('abc',), <traceback object at 0x02A33940>)
except -> (<type 'exceptions.Exception'>, Exception(), <traceback object at 0x02A33990>)
finally -> (<type 'exceptions.Exception'>, Exception(), <traceback object at 0x02A33990>)
希望这样能让事情变得更清楚一些。
17
finally
代码块会在无论有没有出现错误的情况下都被执行,所以正如Josh所说,你很可能不想在这里处理错误。
如果你确实需要获取发生的错误的值,那么你应该在 except
代码块中捕获这个错误,或者妥善处理它,或者重新抛出这个错误,然后在 finally
代码块中使用这个值——要做好准备,如果在执行过程中没有出现错误,这个值可能根本没有被设置。
import sys
exception_name = exception_value = None
try:
# do stuff
except Exception as e:
exception_name, exception_value, _ = sys.exc_info()
raise # or don't -- it's up to you
finally:
# do something with exception_name and exception_value
# but remember that they might still be none
85
不,到了finally
这个阶段,sys.exc_info
的值都是None,无论之前有没有发生异常。你可以使用:
try:
whatever
except:
here sys.exc_info is valid
to re-raise the exception, use a bare `raise`
else:
here you know there was no exception
finally:
and here you can do exception-independent finalization