use 'with' to redirect stdout

Jean-Paul Calderone exarkun at
Mon Feb 11 17:15:40 CET 2008

On Mon, 11 Feb 2008 10:37:18 -0500, Neal Becker <ndbecker2 at> wrote:
>This will work for stdout:
>from __future__ import with_statement
>from contextlib import contextmanager
>import sys
>def redirect(newfile):
>    orig_stdout = sys.stdout
>    sys.stdout = newfile
>    yield
>    sys.stdout = orig_stdout
>if __name__ == "__main__":
>    with redirect (open('stdout', 'w')):
>        print "hello"
>    print "we're back"
>But now, a harder puzzle that I'm stumped on.  Rewrite the above so that it
>doesn't hardcode sys.stdout, ie:
>def redirect (newfile, oldfile=None)
>where default oldfile is sys.stdout.  This seems much trickier.

You just have to parameterize oldfile.  The simplest way is with an object
and an attribute name.

    def redirect(fileholder, filename, newfile):
        orig = getattr(fileholder, filename)
        setattr(fileholder, filename, newfile)
        setattr(fileholder, filename, orig)

    with redirect(sys, 'stdout', open('stdout', 'w')):

Note that this really has nothing to do with redirection specifically,
anymore.  It's a general monkey-patching context manager.


More information about the Python-list mailing list