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

发布于 2024-10-02 13:35:27 字数 493 浏览 8 评论 0原文

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

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

I have an annoying problem when using machine learning library PyML. PyML uses libsvm to train the SVM classifier. The problem is that libsvm outputs some text to standard output. But because that is outside of Python I cannot intercept it. I tried using methods described in problem Silence the stdout of a function in Python without trashing sys.stdout and restoring each function call but none of those help.

Is there any way how to do this. Modifying PyML is not an option.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

喜你已久 2024-10-09 13:35:28

戴夫·史密斯(Dave Smith)在他的 博客。基本上,它很好地包装了 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

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

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

Dave Smith gave a wonderful answer to that on his blog. Basically, it wraps Ignacio's answer nicely:

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

Now, you can surround any function that garbles unwanted noise into stdout like this:

print "You can see this"
with suppress_stdout():
    print "You cannot see this"
print "And you can see this again"

For Python 3 you can use:

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
箹锭⒈辈孓 2024-10-09 13:35:28

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

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

编辑:这些可能会有所帮助,目前没有时间查看:

https://docs.python.org/3/library/contextlib.html#contextlib.redirect_stdout

I had a similar problem with portaudio/PyAudio initialization. I started with Reid's answer, which worked. Although I needed to redirect stderr instead. So, here is an updated, cross-platform version that redirects both:

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

Should be easy to comment out a part you don't need.

Edit: These might help, don't have time to look at the moment:

https://docs.python.org/3/library/contextlib.html#contextlib.redirect_stdout

一花一树开 2024-10-09 13:35:28

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

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

I had the same problem and fixed it like that:

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
南…巷孤猫 2024-10-09 13:35:27

打开/dev/null进行写入,使用os.dup()复制stdout,使用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)

Open /dev/null for writing, use os.dup() to copy stdout, and use os.dup2() to copy your open /dev/null to stdout. Use os.dup2() to copy your copied stdout back to the real stdout after.

devnull = open('/dev/null', 'w')
oldstdout_fno = os.dup(sys.stdout.fileno())
os.dup2(devnull.fileno(), 1)
makesomenoise()
os.dup2(oldstdout_fno, 1)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文