Asked By – Nico Schlömer
I’m using a Python library that does something to an object
and changes it. While doing so, it prints some statistics to stdout, and I’d like to get a grip on this information. The proper solution would be to change
do_something() to return the relevant information,
out = do_something(my_object)
but it will be a while before the devs of
do_something() get to this issue. As a workaround, I thought about parsing whatever
do_something() writes to stdout.
How can I capture stdout output between two points in the code, e.g.,
start_capturing() do_something(my_object) out = end_capturing()
Now we will see solution for issue: How to capture stdout output from a Python function call?
Try this context manager:
from io import StringIO import sys class Capturing(list): def __enter__(self): self._stdout = sys.stdout sys.stdout = self._stringio = StringIO() return self def __exit__(self, *args): self.extend(self._stringio.getvalue().splitlines()) del self._stringio # free up some memory sys.stdout = self._stdout
with Capturing() as output: do_something(my_object)
output is now a list containing the lines printed by the function call.
What may not be obvious is that this can be done more than once and the results concatenated:
with Capturing() as output: print('hello world') print('displays on screen') with Capturing(output) as output: # note the constructor argument print('hello world2') print('done') print('output:', output)
displays on screen done output: ['hello world', 'hello world2']
Update: They added
contextlib in Python 3.4 (along with
redirect_stderr()). So you could use
io.StringIO with that to achieve a similar result (though
Capturing being a list as well as a context manager is arguably more convenient).