I know how to redirect print to a file.
import sys
orig_stdout = sys.stdout
f = file('out.txt', 'w')
sys.stdout = f
for i in range(2):
print ('i = ', i)
sys.stdout = orig_stdout
f.close()
I need to do the same but w/out a file: keep print output in a string list. How to do it in Py3k?
Edit: I can have 3rd party prints in a middle part, not my own prints, so code must be universal for usual "print()".
A built-in file object that is analogous to the interpreter's standard output stream in Python. stdout is used to display output directly to the screen console. Output can be of any form, it can be output from a print statement, an expression statement, and even a prompt direct for input.
import sys
class ListStream:
def __init__(self):
self.data = []
def write(self, s):
self.data.append(s)
sys.stdout = x = ListStream()
for i in range(2):
print ('i = ', i)
sys.stdout = sys.__stdout__
print(x.data)
yields
['i = ', ' ', '0', '\n', 'i = ', ' ', '1', '\n']
Tip: You don't need to save the original sys.stdout
orig_stdout = sys.stdout
since sys.stdout
can be reset with
sys.stdout = sys.__stdout__
You could also add some syntactic sugar by making ListStream
a contextmanager:
import sys
class ListStream:
def __init__(self):
self.data = []
def write(self, s):
self.data.append(s)
def __enter__(self):
sys.stdout = self
return self
def __exit__(self, ext_type, exc_value, traceback):
sys.stdout = sys.__stdout__
By adding the __enter__
and __exit__
methods, you can now use ListStream
in a with-statement
which will automatically reset sys.stdout
for you when Python exits the with-suite
:
with ListStream() as x:
for i in range(2):
print ('i = ', i)
print(x.data)
Instead of rolling your own class, I think it's easiest to replace sys.stdout
(which is simply a TextIOWrapper
) with a StringIO
instance you keep a reference to:
import sys
from io import StringIO
s = StringIO()
sys.stdout = s
print('yo')
print('this is stuff')
print('hi')
s.getvalue()
Out[38]: 'yo\nthis is stuff\nhi\n'
s.getvalue().splitlines()
Out[39]: ['yo', 'this is stuff', 'hi']
As @unutbu says, you can restore the original stdout with sys.stdout = sys.__stdout__
; I particlarly like the idea of using a context manager to temporarily redirect stdout to where you want it to go.
That's something I often do when I need to build a ncurses
application:
import sys
# in this wrapper class you can use a string list instead of a full string like I'm doing
class StdOutWrapper:
lines = []
def write(self,txt):
self.lines.append(txt)
# here is a method so you can get stuff out of your wrapper class
# I am rebuilding the text, but you can do whatever you want!
def get_text(self,beg,end):
return '\n'.join(self.lines)
mystdout = StdOutWrapper()
sys.stdout = mystdout
sys.stderr = mystdout
# do your stuff here that needs to be printed out in a string list
for i in range(2):
print ('i = ', i)
# you don't need to make your variable to cache the `stdout`/`stderr` as they still exist
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
it is working fine with python 3 and python 2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With