bangarangguy
bangarangguy

Reputation: 53

Can I redirect my print statements to multiple outputs without modifying my whole code?

I know that I can redirect print statements to a file: import sys sys.stdout = open("log.txt", "w")

But I need to print to my terminal in the meanwhile. The idea was to write to print statements for each print. Is there a better way to approach this?

Upvotes: 1

Views: 607

Answers (3)

Yardood
Yardood

Reputation: 1

Building on Shivam's answer: you can subclass io.TextIOWrapper to run sys.stdout's normal writes to the console + your own.

class MultipleOutput(io.TextIOWrapper):
    def __init__(self, orig_stdout, *targets):
        # initialize io.TextIOWrapper with the original stdout's buffer
        super().__init__(orig_stdout.buffer)
        self.targets = targets
    def write(self, message):
        # use the super class (original stdout) write method and flush method
        super().write(message)
        super().flush()
        # write to your own targets
        for f in self.targets:
            f.write(message)
            f.flush()

f = open('logs.txt', 'w')
f1 = open('logs1.txt', 'w')
f2 = open('logs2.txt', 'w')
sys_org = sys.stdout
sys.stdout = MultipleOutput(sys_org, f, f1, f2)
print('First Statement.....')
print('Another Statement....')

Upvotes: 0

Shivam
Shivam

Reputation: 51

Yes, you can redirect your code to as many files as you wish as well as to the CLI at the same time. There is a need to introduce a new class to override the existing write method. Try the following snippet, it works for me:

import sys

class MultiPrinter(object):
    def __init__(self, *targets):
        self.targets = targets
    def write(self, obj):
        for f in self.targets:
            f.write(obj)
            f.flush()

f = open('logs.txt', 'w')
f1 = open('logs1.txt', 'w')
f2 = open('logs2.txt', 'w')
sys_org = sys.stdout
sys.stdout = MultiPrinter(sys_org, f, f1, f2)
print('First Statement.....')
print('Another Statement....')

Upvotes: 1

Chandrahas
Chandrahas

Reputation: 335

You can use this answer: How to redirect python subprocess stderr and stdout to multiple files?

The basic idea is to create a multi-output file-type object and assign it to sys.stdout.

import sys

class MultiOut(object):
    def __init__(self, *args):
        self.handles = args

    def write(self, s):
        for f in self.handles:
            f.write(s)

with open('q1', 'w') as f1, open('q2', 'w') as f2, open('q3', 'w') as f3:
    # add all the files (including sys.stdout) to which the output should be written
    sys.stdout = MultiOut(f1, f2, sys.stdout)
    for i, c in enumerate('abcde'):
        print(c, 'out')
        print(i, 'err')

Upvotes: 1

Related Questions