这是我一直想知道的一个问题,但我从来没有找到合适的解决方案.如果我运行一个脚本并且遇到了,那么就说一个IndexError,python打印出错误的行,位置和快速描述并退出.遇到错误时是否可以自动启动pdb?我并不反对在文件顶部添加额外的import语句,也不反对添加一些额外的代码行.
python -m pdb -c continue myscript.py
如果你没有提供-c continue
标志,那么你需要在执行开始时输入'c'(表示继续).然后它将运行到错误点并让你控制那里.正如eqzx所提到的,这个标志是python 3.2中的新增功能,因此早期Python版本需要输入'c'(请参阅https://docs.python.org/3/library/pdb.html).
您可以使用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)
如果您想使用code.interact启动交互式命令行,请使用可以执行异常的框架的本地
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)
使用以下模块:
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
.
Ipython有一个切换此行为的命令:%pdb.它完全符合您的描述,甚至可能更多(通过语法突出显示和代码完成为您提供更多信息性回溯).绝对值得一试!
这不是调试器,但可能同样有用(?)
我知道我听到Guido在某个地方的演讲中提到了这一点.
我刚检查了python - ?,如果使用-i命令,则可以在脚本停止的位置进行交互.
所以给这个脚本:
testlist = [1,2,3,4,5, 0] prev_i = None for i in testlist: if not prev_i: prev_i = i else: result = prev_i/i
你可以得到这个输出!
PS D:\> python -i debugtest.py Traceback (most recent call last): File "debugtest.py", line 10, inresult = prev_i/i ZeroDivisionError: integer division or modulo by zero >>> >>> >>> prev_i 1 >>> i 0 >>>
说实话,我没有用过这个,但我应该,似乎非常有用.
IPython在命令行上使这个变得简单:
python myscript.py arg1 arg2
可以改写成
ipython --pdb myscript.py -- arg1 arg2
或者,类似地,如果调用模块:
python -m mymodule arg1 arg2
可以改写成
ipython --pdb -m mymodule -- arg1 arg2
注意--
停止IPython读取脚本的参数作为它自己的参数.
这也有一个优点,就是调用增强的IPython调试器(ipdb)而不是pdb.
如果你正在使用IPython环境,你可以使用%debug,shell将带你回到带有ipdb环境的违规行以进行检查等.如上所述,另一个选项是使用iPython magic%pdb相同.
如果您使用ipython
,请在启动后输入%pdb
In [1]: %pdb Automatic pdb calling has been turned ON