context manager I/O operation in file
<p>I am using a context manager to wrap the text which would show in terminal and write to file at the same time.</p>

<p>I faced this problem and got the solution, please check
<a href="http://stackoverflow.com/questions/39629435/writing-terminal-output-to-terminal-and-to-a-file">Writing terminal output to terminal and to a file?</a></p>

<p>Cannot change the functions (etc. func1 and func2) problem is after the 'with' statement any output as sys.stdout.write its showing value error: I/O operation in closed file</p>

<p>sample code:</p>

<pre><code>import sys, datetime

class FileWrite(object):
    def __init__(self,log_file_name, stdout):

        self.log_file_name = log_file_name
        self.stdout = stdout

    def __enter__(self):
        self.log_file = open(self.log_file_name, 'a', 0)
        return self

    def __exit__(self, exc_type, exc_value, exc_traceback):
        self.log_file.close()

    def write(self, data):
        self.log_file.write(data)
        self.stdout.write(data)
        self.stdout.flush()
def func1():
     sys.stdout.write('A')
def func2():
     sys.stdout.write('B')
def main():
    with FileWrite(..........., sys.stdout) as sys.stdout:
        func1()
        func2()



    sys.stdout.write('test')

main()
............................
# both output A and B is showing in terminal and writing in file
............................
# writing 'test' only in terminal......
I/O operation in closed file
</code></pre>

<p>You don't really need (or want) to use <code>as</code> here. If the goal is to convert any write to <code>sys.stdout</code> to a write to both <code>sys.stdout</code> and your log file, you need to backup <code>sys.stdout</code> on <code>__enter__</code> and restore it on <code>__exit__</code>, but don't explicitly pass <code>sys.stdout</code> to the constructor, and don't use the <code>__enter__</code> return to replace <code>sys.stdout</code>, because that bypasses the <code>__enter__</code>/<code>__exit__</code> code. Instead, have <code>__enter__</code> and <code>__exit__</code> do the replacing work for you:</p>

<pre><code>class tee_stdout(object):

    def __init__(self, log_file_name):
        self.log_file_name = log_file_name
        self.stdout = None

    def __enter__(self):
        self.log_file = open(self.log_file_name, 'a', 0)

        # Replace sys.stdout while backing it up
        self.stdout, sys.stdout = sys.stdout, self

    def __exit__(self, exc_type, exc_value, exc_traceback):
        sys.stdout = self.stdout  # Restore original sys.stdout
        self.log_file.close()

    def write(self, data):
        self.log_file.write(data)
        self.stdout.write(data)
        self.stdout.flush()
</code></pre>

<p>Now, usage is just:</p>

<pre><code> with tee_stdout(logfilename):
     ... do stuff that uses sys.stdout, explicitly or implicitly ...
 ... when block exits, sys.stdout restored, so normal behavior resumes ...
</code></pre>

<p>Note: If you're targeting Python 3.4 or higher, I'd recommend implementing the class with just <code>write</code>, and then using <code>contextlib.redirect_stdout</code> to avoid reinventing the wheel:</p>

<pre><code>from contextlib import redirect_stdout

class tee_output:
    def __init__(self, *targets):
        self.targets = targets
    def write(self, data):
        for tgt in self.targets:
            tgt.write(data)
            tgt.flush()

with open(logfilename, 'a') as log, redirect_stdout(tee_output(log, sys.stdout)):
    ... logs to logfilename and sys.stdout when sys.stdout written to ...
... undoes redirection ...
</code></pre>

<p>Note: All the above aside, usually, you want to just use <a href="https://docs.python.org/3/library/logging.html" rel="nofollow">the <code>logging</code> module</a> and logger methods for stuff like this. You can pre-configure different loggers, some that go to <code>sys.stdout</code>, some that go to a log file and <code>sys.stdout</code>, some that go just to log files, and use the appropriate one when needed.</p>

python