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

问题描述:

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

有没有办法如何做到这一点。修改PyML不是一个选项。

+0

你检查一下吧,也许它写在sys.stderr和不是sys.stdout! – mouad 2010-11-14 17:39:04

+0

相关:[在Python中将stdout重定向到一个文件?](http://*.com/a/22434262/4279) - 在这种情况下文件是'os.devnull'。 – jfs 2014-05-06 22:54:12

打开/dev/null写入,使用os.dup()复制标准输出,并使用os.dup2()将您打开的/dev/null复制到标准输出。使用os.dup2()将复制的stdout复制回真实的stdout。

devnull = open('/dev/null', 'w') 
oldstdout_fno = os.dup(sys.stdout.fileno()) 
os.dup2(devnull.fileno(), 1) 
makesomenoise() 
os.dup2(oldstdout_fno, 1) 
+0

'oldstdout = os.dup(sys.stdout)'引发一个typeerror'需要一个整数' – Rok 2010-11-14 17:49:44

+3

想通了,sys.stdout.fileno()和devnull.fileno()是必需的,并且在此之后,它的作品,谢谢! ! – Rok 2010-11-14 17:53:00

+0

这对我来说完美无瑕。谢谢! – Will 2013-09-02 09:09:32

我有同样的问题,并固定它像:

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 
+0

如果svm_predict是python的输出,但不是来自python调用的共享库,我相信这是OP的要求。 – 2012-10-17 17:25:55

+0

对我来说,它使用* libsvm *的Python绑定。我猜想PyML的情况是相似的。 Stdout是一个流程属性,即只要不通过子流程使用外部功能,我的包装(以及Ignacio的解决方案)就可以完美地工作。只有当某人打开'/ dev/stdout'来写输出时,它才会失败。 – 2012-10-18 18:36:19

+0

这正是大多数共享库所做的,这就是为什么此解决方案不适用于大多数人的原因。上述解决方案将更接近请求者的需求。 – kamelkev 2013-07-01 18:21:35

戴维·史密斯发表了精彩的回答给了他blog。基本上,它包装伊格纳西奥的回答很好:

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

现在,你可以围绕该garbles不必要的噪音标准输出到像这样的任何功能:

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