使Python中的函数标准输出静音,而不会破坏sys.stdout并恢复每个函数调用


问题内容

Python中是否有一种方法可以在不包装如下所示的函数调用的情况下使stdout静音?

原始破解代码:

from sys import stdout
from copy import copy
save_stdout = copy(stdout)
stdout = open('trash','w')
foo()
stdout = save_stdout

编辑:更正了来自Alex Martelli的代码

import sys
save_stdout = sys.stdout
sys.stdout = open('trash', 'w')
foo()
sys.stdout = save_stdout

这种方法可行,但效率极低。有 是一个更好的办法。有任何想法吗?


问题答案:

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()

更多优化:您只需要用具有no-opwrite方法的对象替换sys.stdout 。例如:

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。我认为它不会比这更干净或更快速;-)。