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

时间:2010-11-14 17:14:16

标签: python libsvm pyml

使用机器学习库PyML时,我遇到了一个恼人的问题。 PyML使用libsvm来训练SVM分类器。问题是libsvm将一些文本输出到标准输出。但因为那是在Python之外我不能拦截它。我尝试使用问题Silence the stdout of a function in Python without trashing sys.stdout and restoring each function call中描述的方法,但没有一个帮助。

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

4 个答案:

答案 0 :(得分:8)

打开/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)

答案 1 :(得分:2)

戴夫史密斯在blog给出了一个很好的答案。基本上,它很好地包装了Ignacio的答案:

def suppress_stdout():
    with open(os.devnull, "w") as devnull:
        old_stdout = sys.stdout
        sys.stdout = devnull
        try:  
            yield
        finally:
            sys.stdout = old_stdout

现在,您可以将任何将不需要的噪音加入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

答案 2 :(得分:0)

我遇到了同样的问题并修复了它:

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

答案 3 :(得分:0)

我在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.')

应该很容易地注释掉不需要的部分。