处理Python pdb不稳定性与输出的最佳方法是什么?
如果我有一个程序,它的 stdout
被重定向了,那么我在使用调试工具 pdb 时,所有的提示信息都会发送到这个重定向的地方,因为这个库是设计成写入 stdout
的。
这个问题有时候很微妙,让我误以为程序卡住了,其实它只是在等待输入。
大家是怎么解决这个问题的呢?(不幸的是,像 winpdb 这样的其他调试工具也不能用)。
3 个回答
如果你是在代码中使用pdb(Python的调试工具),你可以把自己的输出流传给它的构造函数。比如说,sys.__stdout__
可能是个不错的选择。
如果你是从命令行调用pdb,你可以把pdb.py里的main()
函数复制到你自己创建的sane_pdb.py文件里。然后把Pdb()的初始化改成:
pdb = Pdb(stdout=sys.__stdout__)
这样你就可以运行sane_pdb.py,而不是pdb.py了。虽然为了改一行代码你需要复制40行到自己的文件里,这样做并不是特别方便,但这也是一种解决办法。
这个回答是为了补充Ned的内容,目的是为了以一种不需要复制40行代码就能修改其中一行的方式来包装pdb.py的main()
函数:
# sane_pdb.py: launch Pdb with stdout on original
import sys, pdb
def fixed_pdb(Pdb=pdb.Pdb):
'''make Pdb() tied to original stdout'''
return Pdb(stdout=sys.__stdout__)
if __name__ == '__main__':
pdb.Pdb = fixed_pdb
pdb.main()
我不知道这个方法是否真的能解决提问者的问题,但它确实实现了Ned所描述的功能……
这里的问题是,PDB使用了Cmd类,而默认情况下:
use_rawinput = 1
这意味着Cmd会默认使用raw_input()
方法来从控制台读取输入,而不是sys.stdout.readline()
。这样做的原因是raw_input()
支持历史记录(前提是加载了readline
模块)和其他一些有用的功能。唯一的问题是,raw_input()
不支持重定向,所以如果你有一个脚本:
#!/usr/bin/python
name=raw_input("Enter your name: ")
并且运行它
> python test.py
Enter your name: Alex
但是,如果你用输出重定向来运行它,它就会卡住
> python test.py | tee log
这正是PDB使用的方式,也是它卡住的原因。如我所提到的,sys.stdin.readline()
支持重定向,如果你用readline()
重写上面的脚本,它应该就能正常工作。
回到最初的问题,你需要做的就是告诉Cmd不要使用raw_input()
:
Cmd.use_rawinput = 0
或者
pdb = pdb.Pdb()
pdb.use_rawinput=0
pdb.set_trace()