Управление stdout/stderr от Jython
Я вызываю функцию в библиотеке java из jython, которая печатает в stdout. Я хотел бы подавить этот вывод из сценария jython. Я ставлю на Python идиома замена сис.stdout с файлом, подобным объекту (StringIO), но это не захватывает выходные данные библиотеки java. Я предполагаю, что sys.stdout не влияет на программу java. Существует ли стандартное соглашение для перенаправления или подавления этого вывода программно в jython? Если нет, то какими способами я могу достичь вот это?
2 ответа:
Вы можете использовать
System.setOut
, например:Обратите внимание, что это не повлияет на вывод Python, потому что Jython захватывает>>> 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
System.out
, когда он запускается, чтобы вы могли переназначитьsys.stdout
, как и ожидалось.
Я создал контекстный менеджер для имитации (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)