I got a piece of code I'm not pleased with; Does anyone would have a better idea?

def myFunc(verbose=True):
    if not verbose:
        print = functools.partial(globals()['print'], file=open(os.devnull, 'w'))
        # Required, othewise I got the error 'local print variable was referenced before being declared' a few lines below…
        print = globals()['print']

    # Bunch of code with tons of print calls […]

I also tried the classical sys.stdout = open(os.devnull, 'w') but it can't work with my code because my print function is defined as such at the beginning of the code:

print = functools.partial(print, file=codecs.getwriter('utf8')(sys.stdout.buffer)) # Make sure the output is in utf-8

But I'm not really fan about having to use globals twice.

  • 2
    \$\begingroup\$ It might be worth having a look at the logging facilities offered by Python. \$\endgroup\$
    – SylvainD
    Commented Apr 24, 2013 at 9:57
  • \$\begingroup\$ @Josay Are you talking about the logging module? I shall have a look. Last time I tried I couldn't make it work with cgitb but I'm not using cgitb here so may be it could work. I would still prefer to have a solution which would always work. \$\endgroup\$
    – jeromej
    Commented Apr 25, 2013 at 1:25
  • \$\begingroup\$ @Josay Would it also mean that I would have to change my code anyway? (I mean replacing every print in my function or could I just put something on top just like I did here (I thought about implementing this as a decorator)) \$\endgroup\$
    – jeromej
    Commented Apr 25, 2013 at 1:27
  • \$\begingroup\$ @JeromeJ: why are you clobbering a global function? that looks like a no-no, can't you name log or something? \$\endgroup\$
    – tokland
    Commented Apr 25, 2013 at 10:29
  • \$\begingroup\$ @tokland The one at the beginning seems legit to me, everything else is only local (I think I could/should use locals() instead of globals()). About log maybe I could do something like print = someKindOfLogModified? (I don't want to rewrite the code of the functions, some aren't mine) But then, if I use log, some old probs will come back in some of my other codes (that's why I stopped using log, I couldn't make it work everywhere) \$\endgroup\$
    – jeromej
    Commented Apr 26, 2013 at 8:08

1 Answer 1


It depends on what you are looking to do. For localized 'quiet' code, I use this:

class NoStdStreams(object):
    def __init__(self,stdout = None, stderr = None):
        self.devnull = open(os.devnull,'w')
        self._stdout = stdout or self.devnull or sys.stdout
        self._stderr = stderr or self.devnull or sys.stderr

    def __enter__(self):
        self.old_stdout, self.old_stderr = sys.stdout, sys.stderr
        self.old_stdout.flush(); self.old_stderr.flush()
        sys.stdout, sys.stderr = self._stdout, self._stderr

    def __exit__(self, exc_type, exc_value, traceback):
        self._stdout.flush(); self._stderr.flush()
        sys.stdout = self.old_stdout
        sys.stderr = self.old_stderr

then it is as easy as:

with NoStdStreams():
   print('you will never see this')

You could easily adapt it to:

with NoStdStreams(verbose):
    print('you may see this')
  • \$\begingroup\$ I like your idea but I gotta modify my code (and yours) if I want to use it (because of my way of overwriting print so that it doesn't even call sys.stdout) \$\endgroup\$
    – jeromej
    Commented Apr 26, 2013 at 8:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.