在Python 3中,有useful raise ... from ...
feature重新引发异常。也就是说,如何从引发的异常中找到原始(/重新引发的)异常?这是一个(愚蠢的)例子,带有评论来证明我的意思 -
def some_func():
try:
None() # TypeError: 'NoneType' object is not callable
except as err:
raise Exception("blah") from err
try:
some_func()
except as err:
# how can I access the original exception (TypeError)?
答案 0 :(得分:3)
它位于引发异常的__cause__
属性中。取自关于raise ... from ...
的{{3}} {/ p>
from
子句用于异常链接:如果给定,则第二个表达式必须是另一个异常类或实例,然后将作为__cause__
属性附加到引发的异常(可写)。如果未处理引发的异常,则将打印两个异常。
因此,在您的给定方案中,repr
__cause__
属性:
def some_func():
try:
None() # TypeError: 'NoneType' object is not callable
except TypeError as err:
raise Exception("blah") from err
try:
some_func()
except Exception as er:
print(repr(er.__cause__))
将打印出来:
TypeError("'NoneType' object is not callable",)
答案 1 :(得分:2)
每当从异常处理程序(except
子句)引发异常时,原始异常将在新异常__context__
中得到支持。
每当使用from
语法引发异常时,from
中指定的异常将保存在新异常的__cause__
属性中。
在通常的使用案例中,这相当于包含原始例外的__cause__
和__context__
:
def f():
try:
raise Exception('first exception')
except Exception as e:
raise Exception('second exception') from e
try:
f()
except Exception as e:
print('This exception', e)
print('Original exception', e.__context__)
print('Also original exception', e.__cause__)
以下是设置__context__
的示例:
try:
raise Exception('first exception')
except Exception as e:
raise Exception('second exception')
以及设置__cause__
时的示例:
e = Exception('first exception')
raise Exception('second exception') from e