views:

315

answers:

4

I'm running Python 2.4 in a game engine and I want to be able to turn off all prints if needed. For example I'd like to have the prints on for a debug build, and then turned off for a release build. It's also imperative that it's as transparent as possible.

My solution to this in the C code of the engine is having the printf function inside a vararg macro, and defining that to do nothing in a release build.

This is my current solution:

DebugPrints = True
def PRINT (*args):
    global DebugPrints
    if DebugPrints:
     string = ""
     for arg in args:
      string += " " + str(arg)
     print string

It makes it easy to toggle print outs, but there is possibly a better way to format the string. My main issue is that this is actually adding a lot more function calls to the program.

I'm wondering if there is anything you can do to how the print keyword works?

+9  A: 

yes, you can assign sys.stdout to whatever you want. Create a little class with a write method that does nothing:

class DevNull(object):
    def write(self, arg):
        pass

import sys    
sys.stdout = DevNull()
print "this goes to nirvana!"

With the same technique you can also have your prints logged to a file by setting sys.stdout to an opened file object.

Daren Thomas
Don't forget to 'backup' sys.stdout if you wish to re-enable it later. _stdout = sys.stdout; sys.stdout = DevNull()
Christian Witts
With modules like "logging", this method seems a bit ridiculous.
Jeremy Cantrell
'ridiculous' is a bit over the top but i get your point. I should have named the question 'easiest way to toggle prints', maybe?
Nathan Ross Powell
+4  A: 

Don't use print, but make a console class which handles all printing. Simply make calls to the console and the console can decide whether or not to actually print them. A console class is also useful for things like error and warning messages or redirecting where the output goes.

Matt Olenik
+1: using logging or roll your own. But don't use print.
S.Lott
Yeah, an existing logging module is worth looking at. Depending on the scope of the project, a small class might be enough.
Matt Olenik
The built-in logging module is quite good.
S.Lott
+8  A: 

The logging module is the "best" way.. although I quite often just use something simple like..

class MyLogger:
    def _displayMessage(self, message, level = None):
        # This can be modified easily
        if level is not None:
            print "[%s] %s" % (level, message
        else:
            print "[default] %s" % (message)

    def debug(self, message):
        self._displayMessage(message, level = "debug")
    def info(self, message):
        self._displayMessage(message, level = "info")

log = MyLogger()
log.info("test")
dbr
+8  A: 

I know an answer has already been marked as correct, but Python has a debug flag that provides a cleaner solution. You use it like this:

if __debug__:
    print "whoa"

If you invoke Python with -O or -OO (as you normally would for a release build), __debug__ is set to False. What's even better is that __debug__ is a special case for the interpreter; it will actually strip out that code when it writes the pyc/pyo files, making the resulting code smaller/faster. Note that you can't assign values to __debug__, so it's entirely based off those command-line arguments.

DNS
+1: That is useful to know, even if its a bit more effort to implement
Nathan Ross Powell
It's kind of a shame the debug flag is on when you simply do python ./thescript.py (instead of using the -d debug flag)
dbr