从Jython控制stdout / stderr

时间:2011-02-19 01:04:52

标签: java python jython

我在jython的java库中调用一个函数,它打印到stdout。我想从jython脚本中抑制此输出。我尝试使用像object(StringIO)这样的文件替换sys.stdout的python习惯用法,但这不会捕获java库的输出。我猜测sys.stdout不会影响java程序。在jython中是否有以编程方式重定向或抑制此输出的标准约定?如果没有,我可以通过什么方式实现这一目标?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

我创建了一个上下文管理器来模仿(Python3)contextlib的redirect_stdout (gist here)

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