Python 异常链
异常链是一种通过将捕获到的异常包装在新的异常中,并在之后重新抛出的技术。原始异常被保存为新异常的属性(例如cause)。
在处理异常’A’时,可能会发生另一个异常’B’。了解两个异常以便调试问题是有用的。有时,异常处理程序有意重新引发异常,无论是为了提供额外信息还是将异常转换为另一种类型。
在Python 3.x中,可以实现异常链。如果在except块内有任何未处理的异常,它将与正在处理的异常相关联,并包含在错误消息中。
示例
在以下代码片段中,尝试打开一个不存在的文件会引发FileNotFoundError。它被except块检测到。在处理过程中又引发了另一个异常。
try:
open("nofile.txt")
except OSError:
raise RuntimeError("unable to handle error")
它将产生以下 输出 −
Traceback (most recent call last):
File "/home/cg/root/64afcad39c651/main.py", line 2, in <module>
open("nofile.txt")
FileNotFoundError: [Errno 2] No such file or directory: 'nofile.txt'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/cg/root/64afcad39c651/main.py", line 4, in <module>
raise RuntimeError("unable to handle error")
RuntimeError: unable to handle error
raise . . from
如果在raise语句中使用了可选的from子句,它表示异常是另一个异常的直接结果。这在你转换异常时非常有用。from关键字后面的标记应该是异常对象。
try:
open("nofile.txt")
except OSError as exc:
raise RuntimeError from exc
它将生成以下内容 输出 –
Traceback (most recent call last):
File "/home/cg/root/64afcad39c651/main.py", line 2, in <module>
open("nofile.txt")
FileNotFoundError: [Errno 2] No such file or directory: 'nofile.txt'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/cg/root/64afcad39c651/main.py", line 4, in <module>
raise RuntimeError from exc
RuntimeError
从None中引发. . .
如果我们在from子句中使用None而不是异常对象,之前示例中发现的自动异常链接将被禁用。
try:
open("nofile.txt")
except OSError as exc:
raise RuntimeError from None
它将产生以下 输出 −
Traceback (most recent call last):
File "C:\Python311\hello.py", line 4, in <module>
raise RuntimeError from None
RuntimeError
context 和 cause
在except块中引发异常,将自动将捕获的异常添加到新异常的__context__
属性中。同样,您也可以使用表达式 raise … from 语法将__cause__
添加到任何异常中。
try:
try:
raise ValueError("ValueError")
except ValueError as e1:
raise TypeError("TypeError") from e1
except TypeError as e2:
print("The exception was", repr(e2))
print("Its __context__ was", repr(e2.__context__))
print("Its __cause__ was", repr(e2.__cause__))
它将产生以下的 输出 −。
The exception was TypeError('TypeError')
Its __context__ was ValueError('ValueError')
Its __cause__ was ValueError('ValueError')