重新提高Pythonexception并保留堆栈跟踪

我试图捕捉一个线程中的exception,并重新在主线程中提出:

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行,在那里发生了重新抬头。 原来的exception来自第7行。我如何修改线程,以便输出结果如下:

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

你需要使用所有三个参数来提高:

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

将traceback对象作为第三个参数保存在堆栈中。

help('raise')

如果存在第三个对象而不是None ,则它必须是一个回溯对象(请参阅标准types层次结构 ),并将其replace为当前位置作为发生exception的位置。 如果存在第三个对象而不是回溯对象或None ,则会引发TypeErrorexception。 raise的三种expressionforms有助于在except子句中透明地重新引发exception,但如果要重新引发的exception是当前作用域中最近活动的exception,则不应该优先使用expression式进行引发。

在这种情况下,你不能使用noexpression式版本。

这个代码片段在Python 2和3中均可用:

  1 try: ----> 2 raise KeyError('Default key error message') 3 except KeyError as e: 4 e.args = ('Custom message when get re-raised',) #The comma is not a typo, it's there to indicate that we're replacing the tuple that e.args pointing to with another tuple that contain the custom message. 5 raise 

你可以这样写:

 try: raise ValueError('x') except ValueError as ex: self.exc_info = ex 

然后从exception中使用堆栈跟踪?