Получение stdout в рамках того же процесса в Python

У меня есть сценарий Python, который называет набор функций, каждая из которых пишет вывод в stdout. Иногда, когда я выполняю его, я хотел бы отправить вывод в электронном письме (наряду со сгенерированным файлом). Я хотел бы знать, как я могу получить вывод в памяти, таким образом, я могу использовать email модуль для создания электронной почты.

Мои идеи до сих пор были:

  • используйте файл с отображенной памятью (но кажется, что я должен зарезервировать пространство на диске для этого, и я не знаю, какой длины вывод будет),
  • обойдите все это и передайте вывод по каналу к sendmail (но это может быть трудно, если я также хочу присоединить файл),
6
задан danben 16 April 2010 в 17:04
поделиться

3 ответа

Вы сказали, что ваш скрипт «вызывает кучу функций», поэтому я предполагаю, что это функции Python, доступные из вашей программы. Я также предполагаю, что вы используете print для генерации вывода во всех этих функциях. В этом случае вы можете просто заменить sys.stdout на StringIO.StringIO , который перехватит все, что вы пишете. Затем вы можете, наконец, вызвать метод .getValue в вашем StringIO , чтобы получить все, что было отправлено в выходной канал. Это также будет работать для внешних программ, использующих модуль подпроцесса, которые записывают в sys.stdout .

Это дешевый способ. Я бы рекомендовал вам делать вывод, используя модуль logging . У вас будет гораздо больше контроля над тем, как он выводит данные, и вам будет легче управлять им.

3
ответ дан 8 December 2019 в 04:51
поделиться

Захватить вывод довольно просто.

import sys, StringIO
old_stdout = sys.stdout
capturer = StringIO.StringIO()
sys.stdout = capturer
#call functions
print "Hi"
#end functions
sys.stdout = old_stdout
output = capturer.getvalue()
7
ответ дан 8 December 2019 в 04:51
поделиться

Я изменил ответ None, чтобы сделать его контекстным менеджером:

import sys, StringIO, contextlib

class Data(object):
    pass

@contextlib.contextmanager
def capture_stdout():
    old = sys.stdout
    capturer = StringIO.StringIO()
    sys.stdout = capturer
    data = Data()
    yield data
    sys.stdout = old
    data.result = capturer.getvalue()

Использование:

with capture_stdout() as capture:
    print 'Hello'
    print 'Goodbye'
assert capture.result == 'Hello\nGoodbye\n'
13
ответ дан 8 December 2019 в 04:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: