Skip to content

Instantly share code, notes, and snippets.

@otayeby
Last active April 4, 2018 04:21
Show Gist options
  • Save otayeby/6a58c32f4ab298c72b465a0339832564 to your computer and use it in GitHub Desktop.
Save otayeby/6a58c32f4ab298c72b465a0339832564 to your computer and use it in GitHub Desktop.
Redirecting the stdout to a variable while iterating inside a loop.
"""
Reason for publishing this Gist and the use case:
In many cases we use functions in libraries that print the variable we want instead of returning it. This Gist shows
how to get hold of the printed values from these functions and store in a variable. I found the solution in
couple of posts on different forums:
* https://stackoverflow.com/questions/1218933/can-i-redirect-the-stdout-in-python-into-some-sort-of-string-buffer
* https://wrongsideofmemphis.wordpress.com/2010/03/01/store-standard-output-on-a-variable-in-python/
* https://groups.google.com/forum/#!topic/comp.lang.python/tkK6n1oVKhM
* https://bytes.com/topic/python/answers/849106-redirection-standard-output-python-command-python-variable
In addition to the trick demonstrated in these posts, I found a case where I would need to store multiple printouts
inside a loop. This can be achieved by seeking the stdout offsetting the index to location 0 after storing the printout
to the variable at the end of the loop. Otherwise, the stdout will keep appending to the previous printouts.
"""
# Libraries needed: sys and StringIO
import sys
from io import StringIO
# Create a StringIO() object
capture = StringIO()
# Save the original stdout to restore it back later, otherwise we will be unable to print anything after this
save_stdout = sys.stdout
# Reference the location of our capture variable to the stdout, anything returned to the stdout will be directed to it
sys.stdout = capture
# Let's say you want to store the printed values out in an array
store_var = []
# Iteration
for x in range(10):
# Print out that needs to be saved <--- replace with the printout function you are using
print(x + 5)
# Get the values and store it into the variable
store_var.append(capture.getvalue().strip('\n'))
# Empty the capture by seeking the offset of the stdout to index = 0
capture.seek(0)
# Restore the stdout <--- VIP to prevent the suffer
sys.stdout = save_stdout
# Make sure that the stdout is back to normal and successfully stored the output
print('store_var:', store_var)
@gabefair
Copy link

gabefair commented Apr 4, 2018

Very cool! I wonder if save_stdout.write(x+5) could be a substitute for print(x+5)? I haven't tried that.

@otayeby
Copy link
Author

otayeby commented Apr 4, 2018

@gabefair Thanks for your suggestion :) It actually worked with capture.write(str(x + 5)) because when we changed the stdout pointer to the variable capture now the it has the write function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment