Suppressing output of module calling outside library
I have an annoying problem when using machine learning library PyML. PyML uses libsvm to tr开发者_如何学编程ain 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.
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)
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
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
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
精彩评论