10

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

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

4

4 回答 4

11

打开/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)
于 2010-11-14T17:27:10.043 回答
4

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
于 2018-01-11T11:22:45.800 回答
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
于 2011-02-23T08:37:34.290 回答
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.')

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

于 2020-03-05T06:41:41.950 回答