Introduction
When you use print() in python the output goes to standard output or sys.stdout.
You can directly call sys.stdout.write() instead of using print(), but you
can also completely replace sys.stdout with another stream.
This example will show you how to use StringIO memory files to capture
and view stdout.
As always, check the official StringIO documentation for the best information.
Use StringIO to replace stdout
This is good for testing and special cases where you may not have a terminal output.
First, create the StringIO object and then replace sys.stdout with it.
You can write to it directly, or when using print() it will default to going
to sys.stdout and therefore go to our stream object.
To get back the original output stream, it is stored from sys.__stdout__ a special
dunder that always contains the original system stdout.
from io import StringIO # Python 3
import sys
# Create the in-memory "file"
temp_out = StringIO()
# Replace default stdout (terminal) with our stream
sys.stdout = temp_out
print("This is going in to the memory stream")
temp_out.write("Can be written to like normal.\n")
# The original `sys.stdout` is kept in a special
# dunder named `sys.__stdout__`. So you can restore
# the original output stream to the terminal.
sys.stdout = sys.__stdout__
print("Now printing back to terminal")
print("The 'fake' stdout contains: =======")
sys.stdout.write(temp_out.getvalue())
print("=============================")
Note that the StringIO object is the same type of object created when you
call open() and open a file with the r flag.
There is also an io.BytesIO object for byte streams, which is the type
of object you get when calling open() with rb.
Also note that there is sys.stderr and sys.stdin that you can
manipulate in the same ways. They also have the corresponding
sys.__stderr__ and sys.__stdin__ originals.
Conclusion
After reading this, you should know how to create in-memory files for both text and binary data as well as how to temporary replace the default system standard out with your own object to capture data.