Temporarily Redirect stdout/stderr Temporarily Redirect stdout/stderr python python

Temporarily Redirect stdout/stderr


You can also put the redirection logic in a contextmanager.

import osimport sysclass RedirectStdStreams(object):    def __init__(self, stdout=None, stderr=None):        self._stdout = stdout or sys.stdout        self._stderr = stderr 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_stderrif __name__ == '__main__':    devnull = open(os.devnull, 'w')    print('Fubar')    with RedirectStdStreams(stdout=devnull, stderr=devnull):        print("You'll never see me")    print("I'm back!")


To solve the issue that some function might have cached sys.stdout stream as a local variable and therefore replacing the global sys.stdout won't work inside that function, you could redirect at a file descriptor level (sys.stdout.fileno()) e.g.:

from __future__ import print_functionimport osimport sysdef some_function_with_cached_sys_stdout(stdout=sys.stdout):    print('cached stdout', file=stdout)with stdout_redirected(to=os.devnull), merged_stderr_stdout():    print('stdout goes to devnull')    some_function_with_cached_sys_stdout()    print('stderr also goes to stdout that goes to devnull', file=sys.stderr)print('stdout is back')some_function_with_cached_sys_stdout()print('stderr is back', file=sys.stderr)

stdout_redirected() redirects all output for sys.stdout.fileno() to a given filename, file object, or file descriptor (os.devnull in the example).

stdout_redirected() and merged_stderr_stdout() are defined here.


I am not sure what temporary redirection means. But, you can reassign streams like this and reset it back.

temp = sys.stdoutsys.stdout = sys.stderrsys.stderr = temp

Also to write to sys.stderr within print stmts like this.

 print >> sys.stderr, "Error in atexit._run_exitfuncs:"

Regular print will to stdout.