【问题标题】:Get last exception in pdb获取 pdb 中的最后一个异常
【发布时间】:2013-10-13 05:04:41
【问题描述】:

有没有办法在 pdb 中/进入 pdb 之前检查最后一个异常? (使用python 2.7.5)。

立即(是的,我根本没有输入其他命令)在我的代码中引发异常后,我执行sys.exc_info();这只会导致(None, None, None)。此时,我可以做pdb.pm(),pdb 从引发异常的那一点开始。

我希望能够检查这个异常对象(在引发之前它没有存储在变量中)。

http://docs.python.org/2/library/pdb.htmlhttp://docs.python.org/2/library/sys.html 显然没有任何帮助

编辑:我知道set_trace。我想在修改代码之前检查异常。

【问题讨论】:

标签: python exception python-2.7 pdb


【解决方案1】:

这是你要找的吗?

import pdb
try:
    1/0
except Exception as err:
    pdb.set_trace()

% test.py
--Return--
> /home/unutbu/pybin/test.py(8)<module>()->None
-> pdb.set_trace()
(Pdb) err
ZeroDivisionError('integer division or modulo by zero',)
(Pdb) quit

如果您不想修改引发异常的代码,则可以改为重新定义sys.excepthook

import pdb
import sys
def excepthook(type, value, traceback):
    pdb.set_trace()
sys.excepthook = excepthook

1/0

% test.py
--Return--
> /home/unutbu/pybin/test.py(7)excepthook()->None
-> pdb.set_trace()
(Pdb) type
<type 'exceptions.ZeroDivisionError'>
(Pdb) value
ZeroDivisionError('integer division or modulo by zero',)
(Pdb) traceback
<traceback object at 0xb774f52c>
(Pdb) 

【讨论】:

  • 谢谢,太好了。
【解决方案2】:

你可以使用sys.last_value:

>>> no_such_var
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'no_such_var' is not defined
>>> import sys
>>> sys.last_value
NameError("name 'no_such_var' is not defined",)
>>> sys.last_value.args
("name 'no_such_var' is not defined",)

>>> no_such_var
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'no_such_var' is not defined
>>> import pdb, sys
>>> pdb.set_trace()
--Return--
> <stdin>(1)<module>()->None
(Pdb) sys.last_value
NameError("name 'no_such_var' is not defined",)

注意:此解决方案并不完美。当未处理异常并且解释器打印错误消息和堆栈回溯时设置该值。例如,如果使用try .. except .. 捕获异常,则不会设置sys.last_value

【讨论】:

  • 我得到:*** AttributeError: 'module' object has no attribute 'last_value'
  • @falsetru -&gt; print 1 / 0, (Pdb) n, ZeroDivisionError: 'integer division or modulo by zero', (Pdb) import sys, (Pdb) print sys.last_value, *** AttributeError: 'module' object has no attribute 'last_value' - 它不存在(python 2.6)
  • 根据文档,该值仅在异常严重时设置。
  • @falsetru,您对“这三个变量并不总是定义;它们是在未处理异常并且解释器打印错误消息和堆栈回溯”?
  • 我很感激这引起了人们的关注;但请注意,通过 pdb 跟踪时它仍然不起作用。试试this 看看是否可以从 (pdb) 提示符中获取异常。或者,set_trace()1/0 之前,点击n 看看你是否可以在那里得到异常。
【解决方案3】:

您可以通过以下方式检索 pdb/ipdb 中的最新异常:

__exception__

上面其实是(exception, message)的元组。

【讨论】:

  • "NameError: name '__exception__' is not defined"
  • 相同,python 3.8.x
【解决方案4】:

您可以通过pdbpython -m pdb -c continue script.py 运行脚本。它将在未捕获的异常上进入事后调试,并将您放入 pdb 界面。在这里,您可以检查 sys.exc_info() 以获得异常。例如:

$ echo "1 / 0" > script.py 
$ python -m pdb -c continue script.py 
Traceback (most recent call last):
  [...]
  File "/tmp/script.py", line 1, in <module>
    1 / 0
ZeroDivisionError: division by zero
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> /tmp/script.py(1)<module>()
-> 1 / 0
(Pdb) !import sys
(Pdb) p sys.exc_info()
(<class 'ZeroDivisionError'>, ZeroDivisionError('division by zero'), <traceback object at 0x7f3adcf09148>)
(Pdb) interact
*interactive*
>>> import sys
>>> sys.exc_info()
(<class 'ZeroDivisionError'>, ZeroDivisionError('division by zero'), <traceback object at 0x7f3adcf09148>)

【讨论】:

  • 在使用 python 12 年后,我自己在两周前才发现这一点。如果可用,这实际上是一个很好的解决方案。
【解决方案5】:

我偶然发现了这篇文章,但没有一个答案符合我的要求,即重复在问题中的 pdb.pm() 步骤之前喷出的所有错误信息(包括回溯)。这就是最终对我有用的方法:

将以下行添加到您的 .pdbrc 文件中:

import sys
import traceback
alias rethrow traceback.print_exception(sys.last_type, sys.last_value, sys.last_traceback)

现在,下次您在 pdb 环境中时,您只需输入 rethrow,它就会重复您输入 pdb.pm() 之前的所有错误信息。

【讨论】:

  • 这是唯一对我有用的解决方案(python 3.8)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多