Python 3.0 Exception Chaining: raise from

Python 3.0 (but not 2.6) also allows raise statements to have an optional from clause:

raise exception from otherexception

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

When the from is used, the second expression specifies another exception class or instance to attach to the raised exception’s __cause__ attribute. If the raised exception is not caught, Python prints both exceptions as part of the standard error message:

>>> try:
...    1 / 0
... except Exception as E:
...    raise TypeError('Bad!') from E
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: int division or modulo by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
TypeError: Bad!

When an exception is raised inside an exception handler, a similar procedure is followed implicitly: the previous exception is attached to the new exception’s __context__ attribute and is again displayed in the standard error message if the exception goes uncaught. This is an advanced and still somewhat obscure extension, so see Python’s manuals for more details.


Note

Version skew note: Python 3.0 no longer supports the raise Exc, Args form that is still available in Python 2.6. In 3.0, use the raise Exc(Args) instance-creation call form described in this book instead. The equivalent comma form in 2.6 is legacy syntax provided for compatibility with the now defunct string-based exceptions model, and it’s deprecated in 2.6. If used, it is converted to the 3.0 call form. As in earlier releases, a raise Exc form is also allowed—it is converted to raise Exc() in both versions, calling the class constructor with no arguments.