在Python中查找打印语句
有时候我在项目里留下调试用的打印语句,结果很难找到它们。有没有什么办法可以知道是哪一行在打印特定的内容呢?
附带说明
其实聪明地搜索可以解决大部分问题。在Pydev(还有其他一些开发工具)里,有个搜索功能,可以在项目的所有文件中查找。当然,你也可以用grep命令加上-rn选项来达到类似的效果,不过那样你只能看到行号,而不能直接链接到具体位置。
在我的代码中,"print("的使用效果要好得多,通常打印语句里会有额外的文本,可以用正则表达式来搜索。最难的情况是你刚写了print(x),不过这也可以用正则表达式来查找,条件是x里面的值不能以引号开头或结尾(谢谢!BecomingGuro)
10 个回答
7
在Python3中,我使用了一个修改过的打印功能,用来输出文件名、行号和函数名。
import builtins
from inspect import getframeinfo, stack
original_print = print
def print_wrap(*args, **kwargs):
caller = getframeinfo(stack()[1][0])
original_print("FN:",caller.filename,"Line:", caller.lineno,"Func:", caller.function,":::", *args, **kwargs)
builtins.print = print_wrap
71
你问的是静态解决方案,但这里有一个动态的办法。假设你运行代码时,看到有奇怪的打印输出或者写入了sys.stdout,你想知道这些输出是从哪里来的。你可以替换掉sys.stdout,让异常的追踪信息帮助你找到源头:
>>> import sys
>>> def go():
... sys.stdout = None
... print "Hello!"
...
>>> go()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in go
AttributeError: 'NoneType' object has no attribute 'write'
>>> print "Here"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'write'
>>>
如果想要更高级一点的做法,可以把'sys.stdout'替换成一个可以报告打印语句位置的东西。我会用traceback.print_stack()来显示完整的调用栈,但你也可以用sys._getframe()来查看上一级调用,这样可以获取到行号和文件名。
import sys
import traceback
class TracePrints(object):
def __init__(self):
self.stdout = sys.stdout
def write(self, s):
self.stdout.write("Writing %r\n" % s)
traceback.print_stack(file=self.stdout)
sys.stdout = TracePrints()
def a():
print "I am here"
def b():
a()
b()
下面是输出结果
Writing 'I am here'
File "stdout.py", line 19, in <module>
b()
File "stdout.py", line 17, in b
a()
File "stdout.py", line 14, in a
print "I am here"
File "stdout.py", line 9, in write
traceback.print_stack(file=self.stdout)
Writing '\n'
File "stdout.py", line 19, in <module>
b()
File "stdout.py", line 17, in b
a()
File "stdout.py", line 14, in a
print "I am here"
File "stdout.py", line 9, in write
traceback.print_stack(file=self.stdout)
如果你选择这个方法,还可以看看'linecache'模块,它可以用来打印出特定行的内容。想了解更多细节,可以查看traceback.print_stack的实现。