我的脚本中有try
/ finally
子句。是否可以从finally
子句中获取确切的错误消息?
答案 0 :(得分:62)
不,在finally
时间sys.exc_info
全是无,是否有异常
或不。使用:
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
答案 1 :(得分:11)
无论是否抛出异常,finally
块都会被执行,所以Josh指出,你很可能不想在那里处理它。
如果你确实需要引发异常的值,那么你应该在except
块中捕获异常,并适当地处理它或重新引发它,然后在最后阻止 - 如果在执行期间没有引发异常,则期望它可能永远不会被设置。
import sys
exception_name = exception_value = None
try:
# do stuff
except Exception, e:
exception_name, exception_value = sys.exc_info()[:2]
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
答案 2 :(得分:3)
实际上,其他答案有点模糊。所以,让我澄清一下。您始终可以从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()的行为会有所不同,如下例所示。有关更多信息,请参阅How sys.exc_info() works?
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>)
我希望,它会使事情变得更加清晰。
答案 3 :(得分:2)
你想在except子句中做到这一点,而不是finally。
请参阅:http://www.doughellmann.com/articles/Python-Exception-Handling/
答案 4 :(得分:0)
在try
except
阻止之前,只需为可能的例外定义一个空白变量:
import sys
exception = None
try:
result = 1/0
except ZeroDivisionError as e:
exception = sys.exc_info() # or "e"
finally:
if exception:
print(exception)
else:
print('Everything is fine')
在Python 3.6上测试
答案 5 :(得分:0)
否,在 finally
时间 sys.exc_info
为 all-None,无论是否有异常。使用[this代替]:...
另一个回答者是正确的,因为您应该在 except
子句中处理这个问题。
但是,为了后代/记录,这里是对原始问题的回答:
import sys
try:
int("not an integer LOL")
except:
e = sys.exc_info()[1]
# isinstance(e, ValueError) == True
raise # this line is optional; I have it commented for the example output
else:
e = None # you should do this to avoid a NameError
finally:
print("I really wanted to access %s inside of a finally clause. And I'm doing so now."
% repr(e))
这将打印如下内容:
<块引用>我真的很想在 finally 子句中访问 ValueError("invalid literal for int() with base 10: 'not an integer LOL'")
。而我现在正在这样做。