给定一个Exception对象(来源不明),有没有办法获取其回溯?我有这样的代码:
def stuff(): try: ..... return useful except Exception as e: return e result = stuff() if isinstance(result, Exception): result.traceback <-- How?
获得异常后如何从Exception对象提取回溯?
这个问题的答案取决于您使用的Python版本。
很简单:异常带有一个__traceback__包含回溯的属性。此属性也是可写的,并且可以使用with_traceback异常方法方便地设置:
__traceback__
with_traceback
raise Exception("foo occurred").with_traceback(tracebackobj)
这些功能在raise文档中作了最少描述。
raise
答案的这一部分应归功于Vyctor,后者首先发布了此信息。我之所以将其包含在此处,仅是因为此答案停留在顶部,并且Python 3变得越来越普遍。
这很烦人。回溯的麻烦在于它们具有对堆栈框架的引用,而堆栈框架具有对回溯的引用,而回溯具有对具有引用的…的堆栈框架的引用。这给垃圾收集器带来了问题。)
解决此问题的一种好方法是在离开该子句后以手术方式中断循环except,这就是Python 3所做的。Python 2解决方案更加丑陋:为您提供了一个即席函数sys.exc_info(),该函数 仅在 except 子句中有效 。它返回一个元组,其中包含异常,异常类型以及当前正在处理的任何异常的回溯。
except
sys.exc_info()
因此,如果您在except子句中,则可以将的输出sys.exc_info()与traceback模块一起使用来做各种有用的事情:
traceback
>>> import sys, traceback >>> def raise_exception(): ... try: ... raise Exception ... except Exception: ... ex_type, ex, tb = sys.exc_info() ... traceback.print_tb(tb) ... finally: ... del tb ... >>> raise_exception() File "<stdin>", line 3, in raise_exception
但是,随着您的编辑表示,你正在试图获得该回溯 会 ,如果你的异常没有被处理的已打印,它之后 已经 被处理。这个问题要难得多。不幸的是,在没有异常被处理时sys.exc_info返回(None, None, None)。其他相关sys属性也无济于事。sys.exc_traceback不处理任何异常时不推荐使用且未定义;sys.last_traceback看起来很完美,但似乎仅在交互式会话中定义。
sys.exc_info
(None, None, None)
sys
sys.exc_traceback
sys.last_traceback
如果您可以控制引发异常的方式,则可以使用inspect和自定义异常来存储某些信息。但是我不完全确定那将如何工作。
inspect
实话实说,捕获并返回异常是一件不寻常的事情。这可能表明您仍然需要进行重构。