Я использую библиотеку Python, которая что-то делает с объектом
do_something(my_object)
и меняет это. При этом он выводит некоторую статистику на стандартный вывод, и я хотел бы получить эту информацию. Правильным решением было бы изменить, do_something()
чтобы вернуть соответствующую информацию,
out = do_something(my_object)
но пройдет некоторое время, прежде чем разработчики займутся do_something()
этой проблемой. В качестве обходного пути я подумал о разборе всего, что do_something()
записывается в стандартный вывод.
Как я могу захватить вывод stdout между двумя точками кода, например,
start_capturing()
do_something(my_object)
out = end_capturing()
?
Ответы:
Попробуйте этот диспетчер контекста:
Использование:
output
теперь список, содержащий строки, напечатанные при вызове функции.Расширенное использование:
Что может быть неочевидным, так это то, что это можно делать более одного раза, а результаты объединяются:
Вывод:
Обновление : Они добавили
redirect_stdout()
кcontextlib
в Python 3.4 (наряду сredirect_stderr()
). Таким образом, вы можете использоватьio.StringIO
это для достижения аналогичного результата (хотяCapturing
список, а также диспетчер контекста, возможно, более удобны).источник
.extend()
вместо этого, чтобы его можно было использовать конкатентивно, как вы заметили. :-)self._stringio.truncate(0)
послеself.extend()
вызова__exit__()
метода, чтобы освободить часть памяти, удерживаемой_stringio
участником.from io import StringIO
вместо первой строки в диспетчере контекста.В python> = 3.4 contextlib содержит
redirect_stdout
декоратор. Его можно использовать, чтобы ответить на ваш вопрос так:Из документов :
источник
f = io.StringIO() with redirect_stdout(f): logger = getLogger('test_logger') logger.debug('Test debug message') out = f.getvalue() self.assertEqual(out, 'DEBUG:test_logger:Test debug message')
.AssertionError: '' != 'Test debug message'
logger.debug
по умолчанию не пишет в stdout. Если вы замените вызов журнала на,print()
вы должны увидеть сообщение.stream_handler = logging.StreamHandler(sys.stdout)
. И добавьте этот обработчик в мой регистратор. поэтому он должен писать в stdout иredirect_stdout
ловить его, верно?Вот асинхронное решение с использованием файловых каналов.
Пример использования:
источник