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