Python中的异常传递

27 投票
2 回答
41391 浏览
提问于 2025-04-16 10:12

我有一段代码,用来处理一些功能上的异常,整体运行得不错,异常在我想要的时候会被触发,但在调试的时候,错误追踪的结果有时候并不是我想要的样子。

例子A:

>>> 3/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

例子B:

>>> try: 3/0
... except Exception as e: raise e
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: integer division or modulo by zero

在这两个例子中,异常实际上发生在第1行,也就是我们尝试做3/0的地方,但在后面的例子中,系统却告诉我们异常发生在第2行,也就是异常被抛出的地方。

有没有办法在Python中抛出一个异常,让它看起来像是另一个异常,这样可以产生以下输出:

>>> try: 3/0
... except Exception as e: metaraise(e)
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

2 个回答

48

当你重新抛出一个你已经捕获的异常时,比如说:

except Exception as e: raise e

这会重置调用堆栈的信息。就像是抛出了一个新的异常一样。你想要的应该是这样的:

except Exception as e: raise
6

作为参考,解决方案大致如下:

def getException():
    return sys.exc_info()

def metaraise(exc_info):
    raise exc_info[0], exc_info[1], exc_info[2]

try: 3/0
except:
    e = getException()
    metaraise(e)

这其中很棒的一点是,你可以把变量 e 传来传去,并且在其他地方重新抛出它,即使在这个过程中遇到了其他的错误。

撰写回答