Назначение переменной stdout
, как вы делаете, не имеет никакого эффекта, предполагая, что foo
содержит print
операторов - еще один пример того, почему вы никогда не должны импортировать вещи из внутри модуля (как вы делаете здесь), но всегда модуль в целом (затем используйте квалифицированные имена). Между прочим, 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
как только вы определили этот контекст для любого блока, в котором вы не хотите использовать стандартный вывод,
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
. Я не думаю, что это становится чище или быстрее, чем это; -).