Finding a print statement in Python

Question:

Sometimes I leave debugging printing statements in my project and it is difficult to find it. Is there any way to find out what line is printing something in particular?

Sidenote

It appears that searching smart can solve the majority of cases. In Pydev (and other IDEs) there is a Search function which allows searching through all files in a project. Of course, a similar effect can be obtained using grep with the -rn flag, although you only get line numbers instead of direct links.

“print(” works much better within my code and often there is extra text in a print statement that can be searched for with a regular expression. The most difficult case is when you have just written print(x), although this can be searched for a regular expression where the value inside x does not begin or end with quotes (thanks! BecomingGuro)

Asked By: Casebash

||

Answers:

Use grep:

grep -rn print .

Answered By: Pomyk

Using grep with a cleverly constructed regex (does not begin or end with quotes) seems to be your best bet.

Answered By: lprsd

This article can prove very valuable in doing that. Look for the line events and extract the method name from the frame ( if I remember correctly ). More information can be found here

Answered By: Geo

The easiest way would be to use a “debug_print” function instead of plain “print”.

That way you could just redefine the function and be sure you did not miss one…
and still have them handy if you need to debug that code again instead of editing your code back and forth each time.

(Yes leaving debug_print calls can eat some performance : just remove them when it’s the case)

Spotting “debug only” statements in your code is a very good reason to do a diff before comitting any code in your revision control system ! (knowing what to put in your commit comments being a second good reason to do it !)

Answered By: siukurnin

This probably doesnt answer your question directly, but you can get away with tons of print statements if you use pdb (python debugger) in a way to effectively debug and write code.

I know it works, because 99% of time you simple dont wanna print stuff, but you wanna set a breakpoint somewhere and see what the variables are and how far the program has reached.

HTH

Answered By: Jeffrey Jose

It can be hard to find print statements littered in code. You can use grep -r print ., but you may find lots of false positives. An IDE can help you track it down faster.

The correct way to handle this is to use the logging package and have your print statements like this:

logging.info("some value: %s",value)

And then you can turn it on or off with the logging system, which is well understood.

But you know, also use a global variable called debug and set it to True to enable printing. Like this:

(near the top):

 debug=True

(later on)

if debug: 
    print("This is a debug statement. x=",x)

Then, when I want to take out all of the debugging statement, I change the debug to:

debug=False
Answered By: vy32

Use a printf function instead. The following is from Infrequently Answered Python Questions

def printf(format, *args): 
    """Format args with the first argument as format string, and print.
    If the format is not a string, it is converted to one with str.
    You must use printf('%s', x) instead of printf(x) if x might
    contain % or backslash characters."""
    print str(format) % args,

Now, when you move from debug to production, you redefine printf like so:

def printf(format, *args):
    pass

The advantage to doing it this way, is that if you have to go back and maintain the code to add features or fix a bug, you can turn printf back on.

Answered By: Michael Dillon

You asked about static solutions. Here’s a dynamic one. Suppose you run the code and see an errant print or write to sys.stdout, and want to know where it comes from. You can replace sys.stdout and let the exception traceback help you:

>>> 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'
>>> 

For something a bit more sophisticated, replace ‘sys.stdout’ with something which reports where the print statement is located. I’ll use traceback.print_stack() to show the full stack, but you can do other things like using sys._getframe() to look up one stack level in order to get the line number and filename.

import sys
import traceback

class TracePrints(object):
  def __init__(self):    
    self.stdout = sys.stdout
  def write(self, s):
    self.stdout.write("Writing %rn" % s)
    traceback.print_stack(file=self.stdout)

sys.stdout = TracePrints()

def a():
  print "I am here"

def b():
  a()

b()

Here’s the output

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)

If you go this route, see also the ‘linecache’ module, which you can use to print the contents of the line. Take a look at the implementation of traceback.print_stack for details of how to do that.

Answered By: Andrew Dalke

For Python3 i use it patched print for printing out filename, line No and function

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
Answered By: qwerty

Based on Andrew’s answer above I am now using

import sys


class RaiseOnPrint(object):
    def write(self, *args, **kwargs):
        raise RuntimeError("print was called")
    def flush(*args, **kwargs):
        pass

sys.stdout = RaiseOnPrint()

to raise a RuntimeError when print is called.

Below is a sample outcome (in a jupyter notebook):

RuntimeErrorTraceback (most recent call last)
<ipython-input-6-7f55d16e81f1> in <module>()
      5   a()
      6 
----> 7 b()

<ipython-input-6-7f55d16e81f1> in b()
      3 
      4 def b():
----> 5   a()
      6 
      7 b()

<ipython-input-6-7f55d16e81f1> in a()
      1 def a():
----> 2   print "I am here"
      3 
      4 def b():
      5   a()

<ipython-input-5-7e896ec60c87> in write(self, *args, **kwargs)
      4 class RaiseOnPrint(object):
      5     def write(self, *args, **kwargs):
----> 6         raise RuntimeError("print was called")
      7     def flush(*args, **kwargs):
      8         pass

RuntimeError: print was called
Answered By: Marc Wouts
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.