我试图在一个线程中捕获异常并在主线程中重新引发它:
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]
Run Code Online (Sandbox Code Playgroud)
这基本上起作用并产生以下输出:
(<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]
Run Code Online (Sandbox Code Playgroud)
但是,异常的来源指向第16行,其中发生了重新加注.原始异常来自第7行.如何修改主线程以使输出显示:
Traceback (most recent call last):
File "test.py", line 7, in <module>
Run Code Online (Sandbox Code Playgroud) Python 3很整洁
try:
raise OneException('sorry')
except OneException as e:
# after a failed attempt of mitigation:
raise AnotherException('I give up') from e
Run Code Online (Sandbox Code Playgroud)
允许在不丢失上下文的情况下引发后续异常的语法.我在Python 2中可以提出的最好的比喻是
raise AnotherException((e,'I give up')), None, sys.exc_info()[2]
Run Code Online (Sandbox Code Playgroud)
这(e,'')是一个丑陋的黑客,它将原始异常的名称包含在消息中.但是不是有更好的方法吗?
为了弄清楚要避免一些递归需要什么,我需要捕获任何异常(编辑:不只是从Exception派生的,但是所有异常,包括KeyboardInterrupt和用户异常),把它放在一个变量中,然后再重新提升它在捕获区外面.从本质上讲,我正试图推出自己的最终块.这可能吗?
实际问题是调用许多清理函数,如果其中任何一个失败,所有其他函数也应该被调用,那么失败的函数的异常仍然应该传播.这是我目前的解决方案,它需要一个Popen对象列表:
def cleanupProcs(procs):
if not procs:
return
proc = procs.pop(0)
try:
proc.terminate()
proc.wait()
finally:
cleanupProcs(procs)
Run Code Online (Sandbox Code Playgroud)
是否有迭代方法来做到这一点?更优雅的方式?一个更Pythonic的方式?
exception ×3
python ×3
python-2.7 ×1
python-3.x ×1
raise ×1
recursion ×1
stack-trace ×1
traceback ×1