如何在Python的调试器中查看异常的详细信息?

But*_*840 25 python debugging

有时在我调试异常时会引发异常.

例如,考虑以下代码:

def some_function():  # Pretend this function is in a library...
    # ...and deep within the library is an exception:
    raise Exception('An exception message with valuable information.')

import pdb; pdb.set_trace()
try:
    some_function()  # Pretend I am debugging from this point using pdb.
except:
    pass
Run Code Online (Sandbox Code Playgroud)

some_function()调用调试时,如果我发出next命令,我将看到有关引发[和捕获]的异常的以下详细信息:

Exception: Exceptio...ation.',)
Run Code Online (Sandbox Code Playgroud)

这是我正在使用的终端的直接复制/粘贴:

> /tmp/test.py(7)<module>()
-> some_function()  # Pretend I am debugging from this point using pdb.
(Pdb) next
Exception: Exceptio...ation.',)
> /tmp/test.py(7)<module>()
-> some_function()  # Pretend I am debugging from this point using pdb.
(Pdb) 
Run Code Online (Sandbox Code Playgroud)

查看整个异常消息会很有用.我怎么能在pdb中这样做?

Mic*_*man 23

pdb存储异常类型和值__exception__.您可以使用以下命令打印回溯的异常部分pdb:

import traceback; print "".join(traceback.format_exception_only(*__exception__))
Run Code Online (Sandbox Code Playgroud)

例如:

> /tmp/test.py(7)<module>()
-> some_function()  # Pretend I am debugging from this point using pdb.
(Pdb) next
Exception: Exceptio...ation.',)
> /tmp/test.py(7)<module>()
-> some_function()  # Pretend I am debugging from this point using pdb.
(Pdb) import traceback; print "".join(traceback.format_exception_only(*__exception__))
Exception: An exception message with valuable information.

(Pdb) 
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不包括其余的回溯,但所有这些信息都可以通过where命令获得pdb.如果您真的想要完整的回溯,可以将以下内容添加到您的~/.pdbrc文件中或将其粘贴到您的终端中:

!global __currentframe, __stack; from inspect import currentframe as __currentframe, stack as __stack
!global __format_exception_only, __print_stack; from traceback import format_exception_only as __format_exception_only, print_stack as __print_stack
!global __Pdb; from pdb import Pdb as __Pdb

# find the last frame on the stack with an object named "pdb" or "self" that is a pdb.Pdb object
# works for pdb called the usual way, or pdb.pm(), or pdb.set_trace()
!global __pdb; __pdb = [__framerec[0].f_locals.get("pdb") or __framerec[0].f_locals.get("self") for __framerec in __stack() if (__framerec[0].f_locals.get("pdb") or __framerec[0].f_locals.get("self")).__class__ == __Pdb][-1]

alias traceback __print_stack(__pdb.stack[-1][0]); print "".join(__format_exception_only(*__exception__))
Run Code Online (Sandbox Code Playgroud)

然后你可以使用新的traceback别名来获得你想要的东西:

> /tmp/test.py(7)<module>()
-> some_function()  # Pretend I am debugging from this point using pdb.
(Pdb) next
Exception: Exceptio...ation.',)
> /tmp/test.py(7)<module>()
-> some_function()  # Pretend I am debugging from this point using pdb.
(Pdb) traceback
  File "test.py", line 7, in <module>
    some_function()  # Pretend I am debugging from this point using pdb.
  File "test.py", line 3, in some_function
    raise Exception('An exception message with valuable information.')
Exception: An exception message with valuable information.

(Pdb) 
Run Code Online (Sandbox Code Playgroud)

警告:所有这些都依赖于无证件pdbbdb内部构件,很可能会破坏.

  • 谢谢你非常有用的黑客.令人失望的是,没有正常的方法来做一些如此普遍和如此有用的事情.这个hack也适用于pdb ++,所以我通过`ipdb`切换到了. (2认同)

Ste*_*yne 6

python调试器没有"中断异常" - 如果你习惯了这个功能,这可能会非常令人沮丧.因此,我采取了一种记录裂缝痕迹并从那里开始工作的政策.

import logging
try:
    raise Exception('An exception message with valuable information.')
except:
    logging.exception('Error in test code')
Run Code Online (Sandbox Code Playgroud)

如果您使用一个好的IDE(例如带有pydev的Eclipse),则堆栈跟踪的日志条目将被转换为直接跳转到代码中适当位置的超链接.

您可以通过导入回溯来转储代码中任何位置的堆栈跟踪

import traceback
trace = traceback.format_exc()
Run Code Online (Sandbox Code Playgroud)

  • 最好使用`logging.exception('Informative message')`来记录异常回溯,以及有关失败操作的任何信息('信息性消息',可以有参数等).您可以使用`logging.debug(...,exc_info = True)`登录任何级别(例如DEBUG). (2认同)