2011-02-19 20 views
7

Llamo a una función en una biblioteca java desde jython que imprime a stdout. Me gustaría suprimir esta salida del script jython. Intento que el modismo python reemplace sys.stdout con un archivo como objeto (StringIO), pero esto no captura la salida de la biblioteca java. Supongo que sys.stdout no afecta el programa java. ¿Existe una convención estándar para redirigir o suprimir esta salida programáticamente en jython? Si no, ¿de qué manera puedo lograr esto?Controlando stdout/stderr desde Jython

Respuesta

9

Puede utilizar System.setOut, así:

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

Tenga en cuenta que esto no afectará a la salida de Python, porque Jython agarra System.out cuando se pone en marcha para que pueda reasignar sys.stdout como era de esperar.

1

He creado un gestor de contexto para imitar redirect_stdout de contextlib (de python3) (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)