Where are those Print statements?
When I'm debugging Python I tend to sprinkle my code liberally with print statements. Trouble is, I forget which files I added those print statements to and have to waste a few minutes tracking them down. Time which could be better spent doing pretty much anything else.
Not sure why I didn't think of this before, but I hacked together something that automatically prints the file and line of the print statement next to the output.
Here's the code:
import inspect import sys import os class DebugPrint(object): def __init__(self, f): self.f = f def write(self, text): frame = inspect.currentframe() filename = frame.f_back.f_code.co_filename.rsplit(os.sep, 1)[-1] lineno = frame.f_back.f_lineno prefix = "[%s:%s] " % (filename, lineno) if text == os.linesep: self.f.write(text) else: self.f.write(prefix + text) if not isinstance(sys.stdout, DebugPrint): sys.stdout = DebugPrint(sys.stdout)
To use it, save it as ‘debugprint.py’ then imported it somewhere. That's all you need to do. Works on Python 2.7 and probably other 2.X Pythons.
Here's what happens if you do it from the console:
>>> import debugprint >>> print "Hello" [<stdin>:1] Hello
For print statements in your app, you will get something like:
[foo.py:22] Hello
then, instead of
print
You can use
It is amazingly simple, more versatile, and to stop all those print commands you simple change the logger level..
Do you know ack? No need to re-invent the wheel.
Do you know grin? Since we're talking about Python here…
I don't get it.
The overhead of logging is even shorter then your thing.
It is a standard, it is much more pythonic,
scales easily, and if leaving the debug commands in your code
offends your users for some reason (although after changing the loglevel they have no discernible effect),
they can be deleted in the same manner as your print statements.
Actually deleting is even easier because you cannot mistake a proper print with a debug print.
I would of course leave the debug statements in the code for the next bug-finding quest. If it is recommended for core python development, it is good enough for me.
Hiding it with a debug level is not particularly useful, since if it came back it would just be logging spam. And if it remained in the code it could still have a negative impact. For instance if I print out a database query so I can inspect the results – with something like logging.debug(repr(profile)) – it still hits the database and does a lot of string processing regardless if the logging level means the text will not make it to the logs.
So this kind of debug output should definitely be deleted. Either I use debug(“foo”) or print(“foo”). The difference is large irrelevant – especially if the logging is configured for file and line like you said. But at least with ‘print’ I know it is going to the console, no matter how logging is currently configured.
You've just invented something that does the same as logging, only worse. What on earth is the overhead in
import logging; log=logging.getLogger(__name__)
on top of every module. You want that anyway because you also log stuff, don't you? Then, you can simply use log.debug(XXX) where you want to print a trace. Your version control should tell you who entered that statement and when, and if you do a diff before every commit (which I think any sensible developer should do!) you can easily see if you forgot to remove any debug messages that should not be there anymore.
We use the logging module extensively and log thousands of messages a day. Each message is carefully assigned a level and we have gui and command line tools to make sure we can see the messages we need.
But for something temporary where your tracking down a bug there's nothing wrong with print. There are some messages that I just don't want written to files, etc. That's where print can come in. This is a clever hack!
How can people be so stupidly arrogant? There are pluses and minuses and intelligent, well-informed people can choose one or the other.
BTW, I saw an interview with Guido in which he mentioned that when debugging, he likes to use a lot of print statements. Or maybe he doesn't qualify as a “Python ‘expert’”?
You can remove this condition:
Since DebugPrint has just been defined above, the condition will always be
True
. (One could check whether'DebugPrint' in str(type(sys.stdout))
, or even whethernot isinstance(sys.stdout, file)
, but one may also rely on the code being only executed for the first import.Also, the
rsplit()
part can be simplified usingos.path.basename
.