抑制模块外部库调用的输出

Rok*_*Rok 6 python libsvm pyml

使用机器学习库PyML时,我遇到了一个恼人的问题.PyML使用libsvm来训练SVM分类器.问题是libsvm将一些文本输出到标准输出.但因为那是在Python之外我不能拦截它.我尝试使用问题中描述的方法在Python中静默函数的标准输出,而不会破坏sys.stdout并恢复每个函数调用,但这些都没有帮助.

有什么方法可以做到这一点.修改PyML不是一种选择.

Ign*_*ams 9

打开/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)
Run Code Online (Sandbox Code Playgroud)

  • 想通了,sys.stdout.fileno()和devnull.fileno()是必需的,之后就可以了,谢谢! (3认同)
  • 你不应该在最后使用 `devnull.close()` 关闭 devnull 或使用 `with` 语句打开它吗? (2认同)

Man*_* CJ 5

戴夫·史密斯(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
Run Code Online (Sandbox Code Playgroud)

现在,您可以将任何将不需要的噪音混淆到标准输出中的函数包围起来,如下所示:

print "You can see this"
with suppress_stdout():
    print "You cannot see this"
print "And you can see this again"
Run Code Online (Sandbox Code Playgroud)

对于 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
Run Code Online (Sandbox Code Playgroud)

  • 这些解决方案只能抑制 python 中产生的输出。 (4认同)