在出错时自动启动Python调试器
我一直在想一个问题,但一直找不到合适的解决办法。假设我运行一个脚本,结果遇到了一个索引错误(IndexError),这时Python会打印出出错的行号、位置和简单的错误描述,然后程序就结束了。我想知道有没有办法在遇到错误时自动启动调试工具pdb?我并不介意在文件顶部多加一个导入语句,或者多写几行代码。
15 个回答
77
使用下面这个模块:
import sys
def info(type, value, tb):
if hasattr(sys, 'ps1') or not sys.stderr.isatty():
# we are in interactive mode or we don't have a tty-like
# device, so we call the default hook
sys.__excepthook__(type, value, tb)
else:
import traceback, pdb
# we are NOT in interactive mode, print the exception...
traceback.print_exception(type, value, tb)
print
# ...then start the debugger in post-mortem mode.
# pdb.pm() # deprecated
pdb.post_mortem(tb) # more "modern"
sys.excepthook = info
把它命名为 debug
(或者你喜欢的其他名字),然后把它放在你的 Python 路径中的某个地方。
现在,在你的脚本开头,只需要加上 import debug
这一行。
624
python -m pdb -c continue myscript.py
# or
python -m pdb -c continue -m myscript
如果你不加 -c continue
这个选项,那么在程序开始执行时,你需要输入 'c'(表示继续)。这样程序会运行到出错的地方,然后让你在那儿控制程序。正如 eqzx 提到的,这个选项是在 Python 3.2 版本中新增的,所以在更早的 Python 版本中,你必须输入 'c'(继续)才能继续执行(详细信息可以查看 https://docs.python.org/3/library/pdb.html)。
161
你可以使用 traceback.print_exc 来打印出异常的追踪信息。接着,用 sys.exc_info 来提取这个追踪信息,最后调用 pdb.post_mortem 来处理这个追踪信息。
import pdb, traceback, sys
def bombs():
a = []
print a[0]
if __name__ == '__main__':
try:
bombs()
except:
extype, value, tb = sys.exc_info()
traceback.print_exc()
pdb.post_mortem(tb)
如果你想要在出现异常的地方启动一个交互式命令行,并使用当时的局部变量,可以这样做:
import traceback, sys, code
def bombs():
a = []
print a[0]
if __name__ == '__main__':
try:
bombs()
except:
type, value, tb = sys.exc_info()
traceback.print_exc()
last_frame = lambda tb=tb: last_frame(tb.tb_next) if tb.tb_next else tb
frame = last_frame().tb_frame
ns = dict(frame.f_globals)
ns.update(frame.f_locals)
code.interact(local=ns)