当前位置: 首页 > 面试题库 >

从异常对象中提取回溯信息

景建业
2023-03-14
问题内容

给定一个Exception对象(来源不明),有没有办法获取其回溯?我有这样的代码:

def stuff():
   try:
       .....
       return useful
   except Exception as e:
       return e

result = stuff()
if isinstance(result, Exception):
    result.traceback <-- How?

获得异常后如何从Exception对象提取回溯?


问题答案:

这个问题的答案取决于您使用的Python版本。

在Python 3中

很简单:异常带有一个__traceback__包含回溯的属性。此属性也是可写的,并且可以使用with_traceback异常方法方便地设置:

raise Exception("foo occurred").with_traceback(tracebackobj)

这些功能在raise文档中作了最少描述。

答案的这一部分应归功于Vyctor,后者首先发布了此信息。我之所以将其包含在此处,仅是因为此答案停留在顶部,并且Python
3变得越来越普遍。

在Python 2中

这很烦人。回溯的麻烦在于它们具有对堆栈框架的引用,而堆栈框架具有对回溯的引用,而回溯具有对具有引用的…的堆栈框架的引用。这给垃圾收集器带来了问题。)

解决此问题的一种好方法是在离开该子句后以手术方式中断循环except,这就是Python 3所做的。Python
2解决方案更加丑陋:为您提供了一个即席函数sys.exc_info(),该函数
仅在 except 子句中有效 。它返回一个元组,其中包含异常,异常类型以及当前正在处理的任何异常的回溯。

因此,如果您在except子句中,则可以将的输出sys.exc_info()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看起来很完美,但似乎仅在交互式会话中定义。

如果您可以控制引发异常的方式,则可以使用inspect和自定义异常来存储某些信息。但是我不完全确定那将如何工作。

实话实说,捕获并返回异常是一件不寻常的事情。这可能表明您仍然需要进行重构。



 类似资料:
  • 通过方法,我可以获取异常的详细消息,我只需要一些细节,比如该异常的会话信息:、Session id:、.。 注: 具体地说,我使用

  • 问题内容: 如何记录我的Python错误? 问题答案: 在处理程序/块中使用,可将当前异常与跟踪信息一起记录在日志中,并附带一条消息。 现在查看日志文件:

  • Supporting Functions # traceback_example.py import traceback import sys def produce_exception(recursion_level=2): sys.stdout.flush() if recursion_level: produce_exception(recursion_l

  • 问题内容: 我试图从multiprocessing.Process获取一个追溯对象。不幸的是,通过管道传递异常信息不起作用,因为无法腌制回溯对象: 追溯: 还有另一种访问异常信息的方法吗?我想避免传递格式化的字符串。 问题答案: 使用您可以传递包装的异常并在以后重新引发它们: 因此,如果您在远程进程中捕获到异常,则将其包装,然后将其传递回去。调用主流程即可完成工作。

  • 问题内容: 我正在使用backtrace从引发异常的位置获取信息。在我的异常的构造函数中,我将回溯记录存储在std :: string中,并在catch块中查找此类异常,然后打印此回溯记录。 但是我想知道,是否有可能以其他方式在catch块中获得相同的回溯? 问题答案: 我不这么认为。当执行程序在catch块中停止时,将取消堆栈堆栈,并且之前发生的所有操作都不再位于堆栈中。

  • 我有车牌图像(图像像这些示例图像一样被裁剪)。我只想从输入图像中提取印版。 我已经应用了OpenCV Canny边缘检测器,但我不能再进一步了。有人能帮我吗? 我的最终目标是用我的公司标志替换这个标牌。 车牌图像示例: