如何在Traceback之后检查变量?

Col*_*nic 17 python debugging

我的Python脚本崩溃了.为了调试它,我以交互模式运行它python -i example.py

Traceback (most recent call last):
  File "example.py", line 5, in <module>
    main()
  File "example.py", line 3, in main
    message[20]
IndexError: string index out of range
Run Code Online (Sandbox Code Playgroud)

此时,我想检查变量message.我试过了

>>> message
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'message' is not defined
Run Code Online (Sandbox Code Playgroud)

message不在范围内(尽管如此main).这令人沮丧.我该如何检查变量?是否有一个更有用的版本python -i保持崩溃范围(而不是顶级)?


example.py上面使用的代码.不用说,这是一种简化.

def main():
    message = "hello world"
    message[20]

main()
Run Code Online (Sandbox Code Playgroud)

unu*_*tbu 11

仅在存在异常时才转到调试器,您可以定义自定义的excepthook:

import sys
def excepthook(type_, value, tb):
    import traceback
    import pdb
    traceback.print_exception(type_, value, tb)
    pdb.post_mortem(tb)
sys.excepthook = excepthook

def main():
    message = "hello world"
    message[20]

main()
Run Code Online (Sandbox Code Playgroud)

运行该脚本会将您放入pdb和引发异常的框架中:

% script.py
Traceback (most recent call last):
  File "/home/unutbu/pybin/script.py", line 16, in <module>
    main()
  File "/home/unutbu/pybin/script.py", line 14, in main
    message[20]
IndexError: string index out of range
> /home/unutbu/pybin/script.py(14)main()
-> message[20]
(Pdb) p message
'hello world'
(Pdb) p message[20]
*** IndexError: IndexError('string index out of range',)
(Pdb) p len(message)
11
Run Code Online (Sandbox Code Playgroud)

如果定义excepthook看起来像是太多的代码,你可以将它放在一个实用程序模块中,例如utils_debug.py:

import sys
def enable_pdb():
    def excepthook(type_, value, tb):
        import traceback
        import pdb
        traceback.print_exception(type_, value, tb)
        pdb.post_mortem(tb)
    sys.excepthook = excepthook
Run Code Online (Sandbox Code Playgroud)

然后你只需要添加

import utils_debug as UDBG
UDBG.enable_pdb()
Run Code Online (Sandbox Code Playgroud)

到你的script.py.


或者,如果您使用的是IPython,则可以使用%pdb魔术功能(ipdb当出现异常时,您可以使用它).


目前还不清楚为什么size在pdb提示符下检查 会给你一个NameError.(可运行的示例非常有用.)您可以尝试使用bt(backtrace)来检查帧堆栈.如果size在与pdb当前帧不同的帧中定义,则可以使用u(向上)上升到size定义的帧.


Col*_*nic 6

根据Python文档https://docs.python.org/3.4/library/pdb.html

pdb.py也可以作为脚本调用其他脚本进行调试.例如:python -m pdb myscript.py.当作为脚本调用时,如果正在调试的程序异常退出,pdb将自动进入事后调试.

这不完全准确.它实际上在第一行进入调试.

$ python -m pdb example.py
> example.py(1)<module>()
-> def main():
Run Code Online (Sandbox Code Playgroud)

但是,如果您键入c它将继续崩溃

(Pdb) c
Traceback (most recent call last):
  File "C:\Python34\lib\pdb.py", line 1661, in main
    pdb._runscript(mainpyfile)
  File "C:\Python34\lib\pdb.py", line 1542, in _runscript
    self.run(statement)
  File "C:\Python34\lib\bdb.py", line 431, in run
    exec(cmd, globals, locals)
  File "<string>", line 1, in <module>
  File "example.py", line 1, in <module>
    def main():
  File "example.py", line 3, in main
    message[20]
IndexError: string index out of range
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> example.py(3)main()
Run Code Online (Sandbox Code Playgroud)

此时,您可以键入message以检查变量.

-> message[20]
(Pdb) message
'hello world'
Run Code Online (Sandbox Code Playgroud)

Wahey!