我在使用机器学习库PyML时遇到了一个烦人的问题。PyML 使用libsvm来训练 SVM 分类器。问题是 libsvm 将一些文本输出到标准输出。但因为那是在 Python 之外,所以我无法拦截它。我尝试使用问题中描述的方法使 Python 中的函数的标准输出静音,而不破坏 sys.stdout 并恢复每个函数调用,但这些方法都没有帮助。
有什么办法可以做到这一点。修改 PyML 不是一种选择。
打开/dev/null
用于写入,用于os.dup()
复制标准输出,并用于os.dup2()
将您的打开复制/dev/null
到标准输出。之后用于os.dup2()
将复制的标准输出复制回真实的标准输出。
devnull = open('/dev/null', 'w')
oldstdout_fno = os.dup(sys.stdout.fileno())
os.dup2(devnull.fileno(), 1)
makesomenoise()
os.dup2(oldstdout_fno, 1)
Dave Smith 在他的博客上给出了一个绝妙的答案。基本上,它很好地包装了伊格纳西奥的回答:
def suppress_stdout():
with open(os.devnull, "w") as devnull:
old_stdout = sys.stdout
sys.stdout = devnull
try:
yield
finally:
sys.stdout = old_stdout
现在,您可以将任何将不需要的噪音乱码的函数包围到标准输出中,如下所示:
print "You can see this"
with suppress_stdout():
print "You cannot see this"
print "And you can see this again"
对于 Python 3,您可以使用:
from contextlib import contextmanager
import os
import sys
@contextmanager
def suppress_stdout():
with open(os.devnull, "w") as devnull:
old_stdout = sys.stdout
sys.stdout = devnull
try:
yield
finally:
sys.stdout = old_stdout
我有同样的问题并像这样修复它:
from cStringIO import StringIO
def wrapped_svm_predict(*args):
"""Run :func:`svm_predict` with no *stdout* output."""
so, sys.stdout = sys.stdout, StringIO()
ret = svm_predict(*args)
sys.stdout = so
return ret
我在 portaudio/PyAudio 初始化时遇到了类似的问题。我从里德的回答开始,它奏效了。虽然我需要重定向 stderr 。因此,这是一个更新的跨平台版本,可以重定向两者:
import sys, os
# hide diagnostic output
with open(os.devnull, 'w') as devnull:
# suppress stdout
orig_stdout_fno = os.dup(sys.stdout.fileno())
os.dup2(devnull.fileno(), 1)
# suppress stderr
orig_stderr_fno = os.dup(sys.stderr.fileno())
os.dup2(devnull.fileno(), 2)
print('*** stdout should be hidden! ****')
print('*** stderr should be too! ****',
file=sys.stderr)
os.dup2(orig_stdout_fno, 1) # restore stdout
os.dup2(orig_stderr_fno, 2) # restore stderr
print('done.')
应该很容易注释掉不需要的部分。