I have a python project I'm working on whereby instead of print statements I call a function say() so I can print information while in development and log information during production. However, I often forget this and put print statements in the code by mistake. Is there anyway to have the python program read its own source, and exit() if it finds any print statements outside of the function say()?
-
1Why don't you just do it with your text editor? – Blender Jan 18 '13 at 01:04
-
1ctrl f or ctrl r in your text editor.... – nathan hayfield Jan 18 '13 at 01:05
-
My text editor is incapable of running commands on execution of code. – captainandcoke Jan 18 '13 at 01:16
-
1@captainandcoke: I mean, why don't you do a search and replace? You could also incorporate this stuff into a Makefile or a Git commit hook. – Blender Jan 18 '13 at 01:24
-
1All of the above comments are spot on. If you're trying to weed out breaks in convention at runtime, you're either not validating your coding standards (bad), or not double-checking your code (worse). Take the time to go over it yourself--manually, with `grep`, search/replace, whatever is easiest. If you know you're writing the problems, and you know exactly what the problems look like when you write them(i.e. they all contain `print`), you have a much easier code-cleanup job than most developers. – Zac B Jan 18 '13 at 01:35
2 Answers
This can be done using the ast
module. The following code will find any calls of the print
statement and also of the print()
function in case you are on Python 3 or Python 2 with the print_function
future.
import ast
class PrintFinder(ast.NodeVisitor):
def __init__(self):
self.prints_found = []
def visit_Print(self, node):
self.prints_found.append(node)
super(PrintFinder, self).generic_visit(node)
def visit_Call(self, node):
if getattr(node.func, 'id', None) == 'print':
self.prints_found.append(node)
super(PrintFinder, self).generic_visit(node)
def find_print_statements(filename):
with open(filename, 'r') as f:
tree = ast.parse(f.read())
parser = PrintFinder()
parser.visit(tree)
return parser.prints_found
print 'hi'
for node in find_print_statements(__file__):
print 'print statement on line %d' % node.lineno
The output of this example is:
hi
print statement on line 24
print statement on line 26

- 310,957
- 84
- 592
- 636
While I don't recommend doing this, if you really want to you could have the Python interpreter throw an error by redefining the print
statement.
If using Python 3, simply put this near the beginning / top of your code:
print = None
If there are any print
statements, you will get a TypeError: 'NoneType' object is not callable
error.
If using Python 2.x, you might use the idea suggested in another answer to allow Python 2.x to have an overridable print statement.
from __future__ import print_function
print = None
Putting this together with your say()
function, you could do something like:
print_original = print
print = None
def say(data):
print = print_original
# Your current `say()` code here, such as:
print(data) # Could just use `print_original` instead.
# Redefine print to make the statement inaccessible outside this function.
print = None

- 1
- 1

- 3,720
- 4
- 24
- 42
-
`None` is not callable so it would raise an exception when your new `print` "function" was called. Not really what the OP wants. Especially since it will only break when the the code is actually executed. – ThiefMaster Jan 18 '13 at 01:20
-
1The OP states he would like his program to exit() if it encounters any print statements. Throwing an exception will cause the program to exit. Though, I agree this is not a very desirable thing in the first place, but it could work for someone I guess. – Wesley Baugh Jan 18 '13 at 01:24
-
1For me it sounds like he wants to check the whole source and not do it at *some* point during execution – ThiefMaster Jan 18 '13 at 01:26
-
This is probably the simplest solution. It's still a bad idea (as pretty much everyone agrees). – Zac B Jan 18 '13 at 01:33