Is there a way in Python to silence stdout without wrapping a function call like following?
Original Broken Code:
from sys import stdout
from copy import copy
save_stdout = copy(stdout)
stdout = open('trash','w')
foo()
stdout = save_stdout
Edit: Corrected code from Alex Martelli
import sys
save_stdout = sys.stdout
sys.stdout = open('trash', 'w')
foo()
sys.stdout = save_stdout
That way works but appears to be terribly inefficient. There has to be a better way. Any ideas?
Assigning the stdout
variable as you're doing has no effect whatsoever, assuming foo
contains print
statements -- yet another example of why you should never import stuff from inside a module (as you're doing here), but always a module as a whole (then use qualified names). The copy
is irrelevant, by the way. The correct equivalent of your snippet is:
import sys
save_stdout = sys.stdout
sys.stdout = open('trash', 'w')
foo()
sys.stdout = save_stdout
Now, when the code is correct, is the time to make it more elegant or fast. For example, you could use an in-memory file-like object instead of file 'trash':
import sys
import io
save_stdout = sys.stdout
sys.stdout = io.BytesIO()
foo()
sys.stdout = save_stdout
for elegance, a context is best, e.g:
import contextlib
import io
import sys
@contextlib.contextmanager
def nostdout():
save_stdout = sys.stdout
sys.stdout = io.BytesIO()
yield
sys.stdout = save_stdout
once you have defined this context, for any block in which you don't want a stdout,
with nostdout():
foo()
More optimization: you just need to replace sys.stdout with an object that has a no-op write
method. For example:
import contextlib
import sys
class DummyFile(object):
def write(self, x): pass
@contextlib.contextmanager
def nostdout():
save_stdout = sys.stdout
sys.stdout = DummyFile()
yield
sys.stdout = save_stdout
to be used the same way as the previous implementation of nostdout
. I don't think it gets any cleaner or faster than this;-).