从Jython控制stdout/stderr
我在用jython调用一个Java库里的函数,这个函数会往标准输出(stdout)打印信息。我想在jython脚本中屏蔽掉这些输出。我尝试用Python的方式,把sys.stdout替换成一个像文件的对象(StringIO),但是这样并没有捕捉到Java库的输出。我在想,sys.stdout可能对Java程序没有影响。请问在jython中有没有什么标准的方法可以程序化地重定向或屏蔽这些输出?如果没有,还有什么其他方法可以做到这一点呢?
2 个回答
1
我创建了一个上下文管理器,用来模仿(Python3中的)contextlib的redirect_stdout功能,(这里有代码):
'''Wouldn't it be nice if sys.stdout knew how to redirect the JVM's stdout? Shooting star.
Author: Sean Summers <seansummers@gmail.com> 2015-09-28 v0.1
Permalink: https://gist.githubusercontent.com/seansummers/bbfe021e83935b3db01d/raw/redirect_java_stdout.py
'''
from java import io, lang
from contextlib import contextmanager
@contextmanager
def redirect_stdout(new_target):
''' Context manager for temporarily redirecting sys.stdout to another file or file-like object
see contextlib.redirect_stdout documentation for usage
'''
# file objects aren't java.io.File objects...
if isinstance(new_target, file):
new_target.close()
new_target = io.PrintStream(new_target.name)
old_target, target = lang.System.out, new_target
try:
lang.System.setOut(target)
yield None
finally:
lang.System.setOut(old_target)
9
你可以使用 System.setOut
,像这样:
>>> from java.lang import System
>>> from java.io import PrintStream, OutputStream
>>> oldOut = System.out
>>> class NoOutputStream(OutputStream):
... def write(self, b, off, len): pass
...
>>> System.setOut(PrintStream(NoOutputStream()))
>>> System.out.println('foo')
>>> System.setOut(oldOut)
>>> System.out.println('foo')
foo
需要注意的是,这个方法不会影响Python的输出,因为当Jython启动时,它会抓取 System.out
,所以你可以像预期的那样重新设置 sys.stdout
。