我的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定义的帧.
根据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!