python教程—重新引发Python异常并保存堆栈跟踪-Python实用宝典

python教程—重新引发Python异常并保存堆栈跟踪

我试图在线程中捕获异常,并在主线程中重新引发它:这基本上是工作的,并产生以下输出:

我试图捕捉一个异常在线程中,并重新引发它在主线程:

import threading
import sys

class FailingThread(threading.Thread):
    def run(self):
        try:
            raise ValueError('x')
        except ValueError:
            self.exc_info = sys.exc_info()

failingThread = FailingThread()
failingThread.start()
failingThread.join()

print failingThread.exc_info
raise failingThread.exc_info[1]

这基本上工作,并产生以下输出:

    (<type 'exceptions.ValueError'>, ValueError('x',), <traceback object at 0x1004cc320>) Traceback (most recent call last): File "test.py", line 16, in <module> raise failingThread.exc_info[1]

然而,异常的源指向第16行,即重新引发的地方。最初的异常来自第7行。如何修改main线程,使输出读:

    Traceback (most recent call last): File "test.py", line 7, in <module>

回答

在python2中,你需要使用所有三个参数来引发:

    raise failingThread.exc_info[0], failingThread.exc_info[1], failingThread.exc_info[2]

将traceback对象作为第三个参数传入保留堆栈。

从帮助(提高):

如果存在第三个对象而不是没有,那么它必须是回溯
对象(参见节标准类型层次结构),它是
将当前位置替换为
异常发生。如果存在第三个对象而不是a
如果没有回溯对象,则会引发类型错误异常。的
三表达式形式的引发对于重新引发异常非常有用
在except子句中透明地使用,但是不使用表达式
如果要重新提出的异常是最多的,应该首选吗
最近在当前范围内活动异常。

在这种特殊情况下,不能使用no表达式版本。

对于python3(根据注释):

    raise failingThread.exc_info[1].with_traceback(failingThread.exc_info[2])

或者您可以使用raise…从…但这会引发一个链式异常,其原始上下文附加在cause属性中,这可能是您想要的,也可能不是。

​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

本文由 Python实用宝典 作者:Python实用宝典 发表,其版权均为 Python实用宝典 所有,文章内容系作者个人观点,不代表 Python实用宝典 对观点赞同或支持。如需转载,请注明文章来源。
0

发表评论