5.4 如何关闭异常自动关联上下文?¶
当你在处理异常时,由于处理不当或者其他问题,再次抛出另一个异常时,往外抛出的异常也会携带原始的异常信息。
就像这样子。
try:
print(1 / 0)
except Exception as exc:
raise RuntimeError("Something bad happened")
从输出可以看到两个异常信息
Traceback (most recent call last):
File "demo.py", line 2, in <module>
print(1 / 0)
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "demo.py", line 4, in <module>
raise RuntimeError("Something bad happened")
RuntimeError: Something bad happened
如果在异常处理程序或 finally
块中引发异常,默认情况下,异常机制会隐式工作会将先前的异常附加为新异常的
__context__
属性。这就是 Python 默认开启的自动关联异常上下文。
如果你想自己控制这个上下文,可以加个 from 关键字(from
语法会有个限制,就是第二个表达式必须是另一个异常类或实例。),来表明你的新异常是直接由哪个异常引起的。
try:
print(1 / 0)
except Exception as exc:
raise RuntimeError("Something bad happened") from exc
输出如下
Traceback (most recent call last):
File "demo.py", line 2, in <module>
print(1 / 0)
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "demo.py", line 4, in <module>
raise RuntimeError("Something bad happened") from exc
RuntimeError: Something bad happened
当然,你也可以通过with_traceback()
方法为异常设置上下文__context__
属性,这也能在traceback
更好的显示异常信息。
try:
print(1 / 0)
except Exception as exc:
raise RuntimeError("bad thing").with_traceback(exc)
最后,如果我想彻底关闭这个自动关联异常上下文的机制?有什么办法呢?
可以使用 raise...from None
,从下面的例子上看,已经没有了原始异常
$ cat demo.py
try:
print(1 / 0)
except Exception as exc:
raise RuntimeError("Something bad happened") from None
$
$ python demo.py
Traceback (most recent call last):
File "demo.py", line 4, in <module>
raise RuntimeError("Something bad happened") from None
RuntimeError: Something bad happened
(PythonCodingTime)