错误时自动启动pythondebugging器

这是我一直想知道的一个问题,但我从来没有find一个合适的解决scheme。 如果我运行一个脚本,我碰到,让我们说一个IndexError,python打印错误的行,位置和快速描述并退出。 遇到错误时是否可以自动启动pdb? 我不反对在文件顶部有额外的导入语句,也没有额外的代码行。

您可以使用traceback.print_exc打印exception回溯。 然后使用sys.exc_info提取回溯,最后用该回溯调用pdb.post_mortem

import pdb, traceback, sys def bombs(): a = [] print a[0] if __name__ == '__main__': try: bombs() except: type, value, tb = sys.exc_info() traceback.print_exc() pdb.post_mortem(tb) 

如果你想用code.interact开始一个交互式的命令行,你可以使用发生exception的帧的本地语言

 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) 
 python -m pdb -c continue myscript.py 

如果你没有提供-c continue标志,那么当执行开始时你需要input'c'(继续)。 然后它会运行到错误点,并给你在那里控制。 正如eqzx所提到的 ,这个标志是python 3.2中的一个新增加的标记,所以在早期的Python版本中需要input'c'(请参阅https://docs.python.org/3/library/pdb.html )。

使用以下模块:

 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 (或任何你喜欢的),并把它放在你的pythonpath的某处。

现在,在脚本开始时,只需添加一个import debug

这不是debugging器,但可能同样有用(?)

我知道我听到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, in <module> result = prev_i/i ZeroDivisionError: integer division or modulo by zero >>> >>> >>> prev_i 1 >>> i 0 >>> 

说实话我没有用过,但是我应该是,看起来很有用。

Ipython有一个切换这个行为的命令: %pdb 。 它完全符合你所描述的内容,甚至可能更多一些(给你提供更多信息的语法高亮和代码完成回溯)。 这绝对值得一试!

IPython在命令行中简化了这一点:

 python myscript.py arg1 arg2 

可以重写

 ipython --pdb myscript.py -- arg1 arg2 

或者,同样,如果调用一个模块:

 python -m mymodule arg1 arg2 

可以重写

 ipython --pdb -m mymodule -- arg1 arg2 

注意--阻止IPython读取脚本的参数。

这也有调用增强的IPythondebugging器(ipdb)而不是pdb的优点。

你可以把这行代码放在你的代码中:

 import pdb ; pdb.set_trace() 

更多信息: 在任何一行启动pythondebugging器

在开始使用时不必键入c就可以运行:

 python -m pdb -cc <script name> 

Pdb有自己的命令行参数:-cc将在执行开始时执行c(ontinue)命令,程序将不间断地运行直到出现错误。

如果你使用的是IPython环境,你可以只使用%debug,shell会把你带回到ipdb环境的检查等等。上面提到的另一个select是使用iPython magic%pdb,一样。

在python2.7 python -m pdb script.py按继续启动,它会运行到错误,并打破那里debugging。

在层次结构中最顶层的exception类的构造函数中放置一个断点,大部分时间你会看到错误发生的地方。

放置一个断点意味着任何你想要的意思:你可以使用一个IDE,或pdb.set_trace或任何

如果你正在运行一个模块:

 python -m mymodule 

现在,当发生exception时,您想要inputpdb ,请执行以下操作:

 PYTHONPATH="." python -m pdb -cc mymodule/__main__.py 

(或延长你的PYTHONPATH )。 因为您现在正在运行pdb模块,所以需要PYTHONPATH以便在path中find该模块。