如何在Python调试器中查看异常详情?
有时候在调试的时候,会出现异常情况。
比如,看看这段代码:
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
当我在调试 some_function()
这个函数时,如果我输入 next
命令,就会看到关于这个异常的以下信息 [已经被捕获]:
Exception: Exceptio...ation.',)
这是我在终端上工作的内容,直接复制过来的:
> /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)
我想看到完整的异常信息,这样会更有帮助。我该怎么在 pdb 中做到这一点呢?
3 个回答
0
你可以使用:
import sys
sys.exc_info()
在VSCode中,可以在底部的调试栏输入导入的内容。
7
Python的调试器并不会像其他一些工具那样在出现错误时自动中断,这可能会让习惯了这种功能的人感到有些沮丧。因此,我通常会选择记录错误信息,然后从这些信息中找出问题所在。
import logging
try:
raise Exception('An exception message with valuable information.')
except:
logging.exception('Error in test code')
如果你使用一个好的开发环境,比如带有pydev的Eclipse,错误信息中的堆栈跟踪会变成可以点击的链接,直接跳转到代码中的相关位置。
你可以通过导入traceback模块,在代码的任何地方输出堆栈跟踪信息。
import traceback
trace = traceback.format_exc()
29
pdb
会把异常的类型和内容存储在 __exception__
里。你可以用下面的命令在 pdb
中打印出异常的部分:
import traceback; print "".join(traceback.format_exception_only(*__exception__))
举个例子:
> /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)
不过遗憾的是,这个命令不会显示完整的错误追踪信息,但你可以通过 pdb
的 where
命令获取到所有相关的信息。如果你真的想要完整的错误追踪信息,可以把下面的内容添加到你的 ~/.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__))
这样你就可以使用新的 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)
注意:这些内容依赖于一些没有文档说明的 pdb
和 bdb
的内部实现,可能会出现问题。