Как захватить вывод stdout из вызова функции Python?
Я использую библиотеку Python, которая что-то делает с объектом
do_something(my_object)
и изменяет его. При этом он печатает некоторую статистику в stdout, и я хотел бы получить эту информацию. Правильным решением было бы изменить do_something()
чтобы вернуть соответствующую информацию,
out = do_something(my_object)
но это будет некоторое время до разработчиков do_something()
перейти к этой проблеме. В качестве обходного пути я подумал о разборе whatever 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()
to 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()
С документы:
Context manager для временного перенаправления 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.stdout означает, что этот контекст менеджер не подходит для использования в коде библиотеки и большинстве потоков приложения. Он также не влияет на выходные данные подпроцессов. Тем не менее, это по-прежнему полезный подход для многих сценариев утилит.
этот контекстный менеджер является реентерабельным.