3 回答

TA贡献1777条经验 获得超3个赞
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-op write方法的对象替换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。我认为它不会比这更干净或更快速;-)。

TA贡献1824条经验 获得超8个赞
只是为了补充别人已经说过的内容,Python 3.4引入了contextlib.redirect_stdout上下文管理器。它接受将输出重定向到的文件(类)对象。
重定向到/ dev / null将抑制输出:
In [11]: def f(): print('noise')
In [12]: import os, contextlib
In [13]: with open(os.devnull, 'w') as devnull:
....: with contextlib.redirect_stdout(devnull):
....: f()
....:
In [14]:
此解决方案可以用作装饰器:
import os, contextlib
def supress_stdout(func):
def wrapper(*a, **ka):
with open(os.devnull, 'w') as devnull:
with contextlib.redirect_stdout(devnull):
func(*a, **ka)
return wrapper
@supress_stdout
def f():
print('noise')
f() # nothing is printed
在Python 2和3中都可以使用的另一种可能且偶尔有用的解决方案是将/ dev / null作为参数传递给f并使用函数的file参数重定向输出print:
In [14]: def f(target): print('noise', file=target)
In [15]: with open(os.devnull, 'w') as devnull:
....: f(target=devnull)
....:
In [16]:
您甚至可以target完全选择:
def f(target=sys.stdout):
# Here goes the function definition
请注意,您需要
from __future__ import print_function
在Python 2中

TA贡献1796条经验 获得超4个赞
您为什么认为这效率低下?你测试了吗?顺便说一句,它根本不起作用,因为您正在使用该from ... import语句。sys.stdout可以很好地进行替换,但是不要进行复制,也不要使用临时文件。而是打开空设备:
import sys
import os
def foo():
print "abc"
old_stdout = sys.stdout
sys.stdout = open(os.devnull, "w")
try:
foo()
finally:
sys.stdout.close()
sys.stdout = old_stdout
添加回答
举报