Skip to content

Instantly share code, notes, and snippets.

@CMCDragonkai
Last active October 13, 2016 13:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CMCDragonkai/04b9064f005b8ebe704e7addbcc20973 to your computer and use it in GitHub Desktop.
Save CMCDragonkai/04b9064f005b8ebe704e7addbcc20973 to your computer and use it in GitHub Desktop.
Python: Run Code that Prints to STDOUT or STDERR and Capture the Output into a Variable (a.k.a. output buffering to a variable)
# derived from https://wrongsideofmemphis.wordpress.com/2010/03/01/store-standard-output-on-a-variable-in-python/
import sys
from io import StringIO
# from StringIO import StringIO # for python2
# These functions are not thread-safe and are not thread-local, it is global
# across the entire process (all subthreads). It does not apply to child
# processes. If during the execution of `func`, the current thread yields to
# another thread, then you may experience both a leak of the global side-effect
# and/or race conditions on the mutation of the stdout/stderr designators.
# Oh just discovered `contextlib.redirect_stdout` and `contextlib.redirect_stderr`
# They are available on the latest Python 3. They do the same thing, but are also
# re-entrant.
# This means, you can reuse the same context multiple times. However these
# functions should also be re-entrant, but each nested call will print to a new
# buffer. There's no way to reuse the same buffer.
# The contextlib is more flexible, as you get to choose whether you want to
# reuse the same buffer, or start a new buffer! Plus it's in the standard
# library!
def capture_out(func):
try:
old_stdout = sys.stdout
result = StringIO()
sys.stdout = result
func()
result_string = result.getvalue()
return result_string
finally:
sys.stdout = old_stdout
def capture_err(func):
try:
old_stderr = sys.stderr
result = StringIO()
sys.stderr = result
func()
result_string = result.getvalue()
return result_string
finally:
sys.stderr = old_stderr
def capture_out_err(func):
try:
old_stdout = sys.stdout
old_stderr = sys.stderr
result_out = StringIO()
result_err = StringIO()
sys.stdout = result_out
sys.stderr = result_err
func()
result_out_string = result_out.getvalue()
result_err_string = result_out.getvalue()
return (result_out_string, result_err_string)
finally:
sys.stdout = old_stdout
sys.stderr = old_stderr
def capture_out_err_inter(func):
try:
old_stdout = sys.stdout
old_stderr = sys.stderr
result = StringIO()
sys.stdout = result
sys.stderr = result
func()
result_string = result.getvalue()
return result_string
finally:
sys.stdout = old_stdout
sys.stderr = old_stderr
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment