Every novice Pythonista is familiar with the trusty built-in function
print(). Its job is simple: output the string representation of an object or expression.
But let’s say you want to change the behavior of print. Instead of sending its output to the terminal, let’s send that output to a file on the disk. We can accomplish this by redefining the
Printing to a File
The full function signature of print is:
Note the third keyword argument,
file. The default value of
sys.stdout, which represents the terminal output buffer. The only real requirement for the object passed as
file is that it has a
.write() method. You know what has a write method? File handlers.
Let’s redefine the print variable to instead be a wrapper function around the vanilla built-in
print(). The wrapped
print() needs to be referenced through the
builtins module so that we don’t define a recursive function.
Now, when we call
print(), no output is displayed in the terminal. However, if we read the contents of
log.txt, we can see that our redefined
print() has written to the file.
Print as a Buffer Object
Let’s make it weird. We can actually redefine
print() to be a buffer object that stores all the strings that are passed to it for printing. Instead of a function,
StringIO is a in-memory text buffer that works similarly to a file handler. In fact, file handlers and
StringIO both implement the abstract base class
IOBase, which means they have many of the same methods defined.
Here’s a simple example of how to use
Let’s define a new subclass of
PrintWrapper. We’re also going to define a
__call__ magic method on this new class.
__call__ allows you to define how an instance of a class behaves when it is called like a function.
Strings that you have printed are seperated by
\n when you call print.getvalue(), but you can define a different seperator by passing it as a string to the
end= keyword argument of
Why would you ever want to do any of this? Let’s say you are building a web-based programming environment like CoderPad. When a user calls
print(), you wouldn’t want the Python interpreter running on the server to send the printed statement to stdout. You want it outputted to a handler that transmits it to the user’s browser over the Internet. There are probably other ways to accomplish this, but redefining
print() behind the scenes is one possibility.
Edit: As Reddit user Dasher38 points out, there’s a context manager in the standard library
contextlib.redirect_stdout that is better suited for redirecting the output of a web-based programming environment backend.
redirect_stdout redirects everything sent to
sys.stdout (including printed statements) to a specified file-like object.
This is the first of a series of blog entries I’m calling “baby snakes”, bits of Python arcana aimed at intermediate and advanced Python developers. Check back soon for more!