在Python中查找打印语句

32 投票
10 回答
12714 浏览
提问于 2025-04-15 15:20

有时候我在项目里留下调试用的打印语句,结果很难找到它们。有没有什么办法可以知道是哪一行在打印特定的内容呢?

附带说明

其实聪明地搜索可以解决大部分问题。在Pydev(还有其他一些开发工具)里,有个搜索功能,可以在项目的所有文件中查找。当然,你也可以用grep命令加上-rn选项来达到类似的效果,不过那样你只能看到行号,而不能直接链接到具体位置。

在我的代码中,"print("的使用效果要好得多,通常打印语句里会有额外的文本,可以用正则表达式来搜索。最难的情况是你刚写了print(x),不过这也可以用正则表达式来查找,条件是x里面的值不能以引号开头或结尾(谢谢!BecomingGuro)

10 个回答

5

这篇文章在这方面非常有用。你可以查找line事件,并从框架中提取方法名称(如果我没记错的话)。更多信息可以在这里找到。

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的实现。

撰写回答