2011-02-19 71 views
7

我打电话给标准输出从jython调用java库中的函数。我想从jython脚本中取消这个输出。我尝试用像对象(StringIO)这样的文件替换sys.stdout的python习语,但是这并不捕获java库的输出。我猜sys.stdout不会影响Java程序。有没有一个标准的惯例重定向或压制这种输出在jython编程方式?如果我不能通过什么方式来实现这一点?从Jython控制标准输出/标准错误

回答

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

我创建了一个上下文管理器模仿(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 <[email protected]> 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) 
相关问题