Monday, December 7, 2009

Python debugging trick

A personal project of mine is in python and littered with some heavy debugging statements. 'Heavy' as in there are many of them, and even more so in that they're costly to execute. My debugging method was:


def noop(*args):
pass

def debug(string):
print("##DEBUG >>> {0}".format(string))

debug=noop

def foo(...):
...
debug("blah blah " + repr(baz))
...


Debugging is then enabled by commenting out the debug=noop line, or disabled by uncommenting it.
The downside is that the repr() is executed whether or not debugging is enabled; so if they turn out to be large or expensive to calculate, they hurt performance in all cases.

In the car on the way to lunch today with a colleague, I was bemoaning this state of affairs and wishing python had some kind of macros. His suggested solution was to eval a string; my mildly better counterproposal was to use python's excuse for a closure:


def noop(*args):
pass

def debug(stringfunc):
for line in stringfunc():
print("##DEBUG >>> {0}".format(line))

debug=noop

def foo(...):
...
debug(lambda : "blah blah " + repr(baz))
...


This saves the evaluation of the repr() until the lambda is eval'd... which may be never. The more conventional way of doing this is:



DEBUG=false

def debug(string):
print("##DEBUG >>> {0}".format(string))

def foo(...):
...
if DEBUG: debug("blah blah" + repr(baz))
...


which always seemed much more... redundant, I guess... to me. Either one is a solution to the problem of extra debug overhead, however.