Как захватить вывод stdout из вызова функции Python?
Я использую библиотеку Python, которая что-то делает с объектом
do_something(my_object)
и изменяет его. При этом он печатает некоторую статистику в stdout, и я хотел бы получить доступ к этой информации. Правильным решением было бы изменить do_something()
чтобы вернуть соответствующую информацию,
out = do_something(my_object)
но это будет некоторое время до разработчиков do_something()
перейти к этому вопросу. В качестве обходного пути, я думал о разборе все, что do_something()
пишет в stdout.
как может Я захватываю вывод stdout между двумя точками в коде, например,
start_capturing()
do_something(my_object)
out = end_capturing()
?
2 ответа:
попробуйте этот контекстный менеджер:
from cStringIO import StringIO import sys class Capturing(list): def __enter__(self): self._stdout = sys.stdout sys.stdout = self._stringio = StringIO() return self def __exit__(self, *args): self.extend(self._stringio.getvalue().splitlines()) del self._stringio # free up some memory sys.stdout = self._stdout
использование:
with Capturing() as output: do_something(my_object)
output
теперь это список, содержащий строки, напечатанные вызовом функции.дополнительные функции:
что не может быть очевидным, так это то, что это может быть сделано более одного раза, и результаты объединены:
with Capturing() as output: print 'hello world' print 'displays on screen' with Capturing(output) as output: # note the constructor argument print 'hello world2' print 'done' print 'output:', output
выход:
displays on screen done output: ['hello world', 'hello world2']
обновление: они добавил
redirect_stdout()
доcontextlib
в Python 3.4 (вместе сredirect_stderr()
). Так что вы могли бы использоватьio.StringIO
С тем, чтобы добиться аналогичного результата (хотяCapturing
быть списком, а также менеджером контекста, возможно, более удобно).
в python >= 3.4, contextlib содержит
redirect_stdout
декоратор. Он может быть использован, чтобы ответить на ваш вопрос так:import io from contextlib import redirect_stdout f = io.StringIO() with redirect_stdout(f): do_something(my_object) out = f.getvalue()
С документы:
контекстный менеджер для временного перенаправления sys.стандартный вывод в другой файл или файлоподобный объект.
этот инструмент добавляет гибкость к существующим функциям или классам выход жестко подключен к stdout.
например, вывод help () обычно отправляется в sys.стандартный вывод. Вы можно захватить этот вывод в строку, перенаправив вывод на Ио.StringIO объекта:
f = io.StringIO() with redirect_stdout(f): help(pow) s = f.getvalue()
чтобы отправить вывод help() в файл на диске, перенаправьте вывод на обычный файл:
with open('help.txt', 'w') as f: with redirect_stdout(f): help(pow)
чтобы отправить вывод help () в sys.поток stderr:
with redirect_stdout(sys.stderr): help(pow)
обратите внимание, что глобальный побочный эффект на sys.стандартный вывод означает, что в этом контексте менеджер не подходит для использования в коде библиотеки и наиболее резьбовой приложения. Это также не влияет на выход подпроцессов. Тем не менее, это все еще полезный подход для многих сценариев утилит.
этот контекстный менеджер является реентерабельным.