>>> sys.stdout = temp # restore original stream
>>> buff.getvalue()
'42 spam 3.141\n'
Note that there is also an io.BytesIO class with similar behavior, but which maps file
operations to an in-memory bytes buffer, instead of a str string:
>>> from io import BytesIO
>>> stream = BytesIO()
>>> stream.write(b'spam')
>>> stream.getvalue()
b'spam'
>>> stream = BytesIO(b'dpam')
>>> stream.read()
b'dpam'
Due to the sharp distinction that Python 3X draws between text and binary data, this
alternative may be better suited for scripts that deal with binary data. We’ll learn more
about the text-versus-binary issue in the next chapter when we explore files.
Capturing the stderr Stream
We’ve been focusing on stdin and stdout redirection, but stderr can be similarly reset
to files, pipes, and objects. Although some shells support this, it’s also straightforward
within a Python script. For instance, assigning sys.stderr to another instance of a class
such as Output or a StringIO object in the preceding section’s example allows your script
to intercept text written to standard error, too.
Python itself uses standard error for error message text (and the IDLE GUI interface
intercepts it and colors it red by default). However, no higher-level tools for standard
error do what print and input do for the output and input streams. If you wish to print
to the error stream, you’ll want to call sys.stderr.write() explicitly or read the next
section for a print call trick that makes this easier.
Redirecting standard errors from a shell command line is a bit more complex and less
portable. On most Unix-like systems, we can usually capture stderr output by using
shell-redirection syntax of the form command > output 2>&1. This may not work on some
platforms, though, and can even vary per Unix shell; see your shell’s manpages for more
details.
Redirection Syntax in Print Calls
Because resetting the stream attributes to new objects was so popular, the Python
print built-in is also extended to include an explicit file to which output is to be sent.
A statement of this form:
print(stuff, file=afile) # afile is an object, not a string name
Standard Streams | 127