问题
Basically, the title.
I am trying to trace down where a spurious print happens in a large codebase, and I would like to break, or somehow get a stack trace whenever a print "happens." Any ideas?
回答1:
For this particular case you can redirect stdout
to a helper class that prints the output and its caller. You can also break on one of its methods.
Full example:
import sys
import inspect
class PrintSnooper:
def __init__(self, stdout):
self.stdout = stdout
def caller(self):
return inspect.stack()[2][3]
def write(self, s):
self.stdout.write("printed by %s: " % self.caller())
self.stdout.write(s)
self.stdout.write("\n")
def test():
print 'hello from test'
def main():
# redirect stdout to a helper class.
sys.stdout = PrintSnooper(sys.stdout)
print 'hello from main'
test()
if __name__ == '__main__':
main()
Output:
printed by main: hello from main
printed by main:
printed by test: hello from test
printed by test:
You can also just print inspect.stack()
if you need more thorough information.
回答2:
The only thin I can think of would be to replace sys.stdout
, for example with a streamwriter as returned by codecs.getwriter('utf8')
. Then you can set a breakpoint on it's write
method in pdb. Or replace it's write
method with debugging code.
import codecs
import sys
writer = codecs.getwriter('utf-8')(sys.stdout) # sys.stdout.detach() in python3
old_write = writer.write
def write(data):
print >>sys.stderr, 'debug:', repr(data)
# or check data + pdb.set_trace()
old_write(data)
writer.write = write
sys.stdout = writer
print 'spam', 'eggs'
来源:https://stackoverflow.com/questions/10742501/is-there-a-trick-to-break-on-the-print-builtin-with-pdb