I'm trying to create a mechanism to redirect print
outputs to a number of variables. Following code simulates what I'm looking for :-
import sys
import io
class MultiOut(object):
def __init__(self, stream_out):
self.terminal = sys.stdout
self.output = stream_out
def write(self, message):
self.terminal.write(message)
self.output.write(message)
def flush(self):
self.terminal.flush()
self.output.flush()
vals = {'a1': io.StringIO(), 'a2': io.StringIO(), 'a3': io.StringIO()}
for i,val in enumerate(vals):
sys.stdout = MultiOut(vals[val])
[print(x**i, end=' ') for x in range(11)]
print("\n")
with open('temp.txt', 'w') as f:
for x in vals:
f.write(f"{x} :-\n")
f.write(vals[x].getvalue())
f.write(f"{'='*50}\n")
File Output (tmp.txt) :-
a1 :-
1 1 1 1 1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 10
0 1 4 9 16 25 36 49 64 81 100
==================================================
a2 :-
0 1 2 3 4 5 6 7 8 9 10
0 1 4 9 16 25 36 49 64 81 100
==================================================
a3 :-
0 1 4 9 16 25 36 49 64 81 100
==================================================
What I'm trying to do here is to redirect various 'sections' of the outputs to different variables of vals - a1, a2, a3
and dump all the outputs to the terminal. Strangely, each successive variable contains data starting from that point till the end. Is there a way to avoid this issue and save each section in a different variable ?
The issue is you're replacing sys.stdout with your object:
and in your object init, you're setting sys.stdout as object attribute
On the second iteration, when executing this statement
sys.stdout is the replacement from the first iteration, which includes the first
MultiOut
object.I hope this makes sense.
Rather then modifying stdout, I'd use the logging module to achieve what you want.