Python 异常传播
我正在制作一个工具,当出现异常时,它会向上层传递,同时在异常中添加关于异常上下文的新数据。问题是,当异常到达最上层时,所有额外的上下文数据都在里面,但只显示了最新的调用栈信息。有没有简单的方法可以让异常显示它最初抛出时的调用栈,而不是最后的调用栈?还是说我应该在异常第一次传递时就抓取原始的调用栈?
比如,下面这段代码:
def a():
return UNBOUND
def b():
try:
a()
except Exception as e:
raise e
b()
会产生以下异常:
Traceback (most recent call last):
File "test.py", line 8, in <module>
b()
File "test.py", line 7, in b
raise e
NameError: global name 'UNBOUND' is not defined
理想情况下,我希望能以某种方式向用户展示这个:
Traceback (most recent call last):
File "test.py", line 8, in <module>
File "test.py", line 2, in a
return UNBOUND
NameError: global name 'UNBOUND' is not defined
这样可以指向错误最初发生的那一行。
1 个回答
38
Python中的异常处理有点像Java,实际上有一种方法可以让异常重新抛出,而不会丢失调用栈的信息。
你只需要使用 raise
而不带任何参数。这样做的结果是:
Traceback (most recent call last):
File "./exc.py", line 11, in <module>
b()
File "./exc.py", line 7, in b
a()
File "./exc.py", line 4, in a
return UNBOUND
NameError: global name 'UNBOUND' is not defined
即使你只是简单地使用 raise
而不加参数,你也可以对 e
对象进行一些修改,比如:
e.args = ("hi!",)
raise
这实际上会改变异常的提示信息。你可能还可以通过这种方式改变其他选项,而不会破坏调用栈的信息。