jer*_*emy 194 python debugging
这是我一直想知道的一个问题,但我从来没有找到合适的解决方案.如果我运行一个脚本并且遇到了,那么就说一个IndexError,python打印出错误的行,位置和快速描述并退出.遇到错误时是否可以自动启动pdb?我并不反对在文件顶部添加额外的import语句,也不反对添加一些额外的代码行.
Cat*_*lin 399
python -m pdb -c continue myscript.py
Run Code Online (Sandbox Code Playgroud)
如果你没有提供-c continue
标志,那么你需要在执行开始时输入'c'(表示继续).然后它将运行到错误点并让你控制那里.正如eqzx所提到的,这个标志是python 3.2中的新增功能,因此早期Python版本需要输入'c'(请参阅https://docs.python.org/3/library/pdb.html).
Flo*_*sch 114
您可以使用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)
Run Code Online (Sandbox Code Playgroud)
如果您想使用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)
Run Code Online (Sandbox Code Playgroud)
tzo*_*zot 63
使用以下模块:
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
Run Code Online (Sandbox Code Playgroud)
将它命名debug
(或任何你喜欢的)并将其放在python路径中的某个位置.
现在,在脚本开始时,只需添加一个import debug
.
Lat*_*ius 41
Ipython有一个切换此行为的命令:%pdb.它完全符合您的描述,甚至可能更多(通过语法突出显示和代码完成为您提供更多信息性回溯).绝对值得一试!
mon*_*kut 31
这不是调试器,但可能同样有用(?)
我知道我听到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
Run Code Online (Sandbox Code Playgroud)
你可以得到这个输出!
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
>>>
Run Code Online (Sandbox Code Playgroud)
说实话,我没有用过这个,但我应该,似乎非常有用.
wod*_*dow 19
IPython在命令行上使这个变得简单:
python myscript.py arg1 arg2
Run Code Online (Sandbox Code Playgroud)
可以改写成
ipython --pdb myscript.py -- arg1 arg2
Run Code Online (Sandbox Code Playgroud)
或者,类似地,如果调用模块:
python -m mymodule arg1 arg2
Run Code Online (Sandbox Code Playgroud)
可以改写成
ipython --pdb -m mymodule -- arg1 arg2
Run Code Online (Sandbox Code Playgroud)
注意--
停止IPython读取脚本的参数作为它自己的参数.
这也有一个优点,就是调用增强的IPython调试器(ipdb)而不是pdb.
如果你正在使用IPython环境,你可以使用%debug,shell将带你回到带有ipdb环境的违规行以进行检查等.如上所述,另一个选项是使用iPython magic%pdb相同.
如果您使用ipython
,请在启动后输入%pdb
In [1]: %pdb
Automatic pdb calling has been turned ON
Run Code Online (Sandbox Code Playgroud)
小智 5
要使其运行而不必在开始时键入 c,请使用:
python -m pdb -c c <script name>
Run Code Online (Sandbox Code Playgroud)
Pdb有自己的命令行参数:-cc将在执行开始时执行c(ontinue)命令,程序将不间断地运行,直到出现错误。