Назначение переменной stdout
, как вы делаете, не имеет никакого эффекта, предполагая, что foo
содержит print
утверждения - еще один пример того, почему вы никогда не должны импортировать материал из внутри a модуль (как вы здесь делаете), но всегда модуль в целом (затем используйте квалифицированные имена). Кстати, copy
не имеет значения. Правильный эквивалент вашего фрагмента:
import sys
save_stdout = sys.stdout
sys.stdout = open('trash', 'w')
foo()
sys.stdout = save_stdout
Теперь, когда код верен, настало время сделать его более элегантным или быстрым. Например, вы можете использовать файл-подобный объект в памяти вместо файла 'trash':
import sys
import io
save_stdout = sys.stdout
sys.stdout = io.BytesIO()
foo()
sys.stdout = save_stdout
для элегантности, лучше использовать контекст , например:
import contextlib
import io
import sys
@contextlib.contextmanager
def nostdout():
save_stdout = sys.stdout
sys.stdout = io.BytesIO()
yield
sys.stdout = save_stdout
после того, как вы определили этот контекст, для любого блока, в котором вы не хотите stdout,
with nostdout():
foo()
Дополнительная оптимизация: вам просто нужно заменить sys.stdout на объект, который имеет метод no-op write
. Например:
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
используется так же, как предыдущая реализация nostdout
. Я не думаю, что он становится чище или быстрее, чем это; -).