While it's common practice to redirect stdout/stderr to external files, it may be necessary to do so temporarily, within the scope of a specific method.
Existing solutions typically replace the entire output streams, leaving local copies of these streams unaffected. This can lead to issues when methods use local copies of the streams.
To address this limitation, we can implement the redirection logic using a contextmanager:
<code class="python">import os import sys class RedirectStdStreams(object): def __init__(self, stdout=None, stderr=None): self._stdout = stdout or sys.stdout self._stderr = stderr or sys.stderr def __enter__(self): self.old_stdout, self.old_stderr = sys.stdout, sys.stderr self.old_stdout.flush(); self.old_stderr.flush() sys.stdout, sys.stderr = self._stdout, self._stderr def __exit__(self, exc_type, exc_value, traceback): self._stdout.flush(); self._stderr.flush() sys.stdout = self.old_stdout sys.stderr = self.old_stderr</code>
This class allows for temporary redirection of both stdout and stderr.
To demonstrate usage, we can redirect the output to /dev/null and observe the behavior:
<code class="python">if __name__ == '__main__': devnull = open(os.devnull, 'w') print('Fubar') with RedirectStdStreams(stdout=devnull, stderr=devnull): print("You'll never see me") print("I'm back!")</code>
In this example, the message "You'll never see me" is suppressed while the redirection is active, but is visible afterwards, confirming that the redirection is temporary and affects only the scope within the context manager.
The above is the detailed content of How to Temporarily Redirect stdout/stderr in Python with a Context Manager?. For more information, please follow other related articles on the PHP Chinese website!