У меня есть сценарий Python, который называет набор функций, каждая из которых пишет вывод в stdout. Иногда, когда я выполняю его, я хотел бы отправить вывод в электронном письме (наряду со сгенерированным файлом). Я хотел бы знать, как я могу получить вывод в памяти, таким образом, я могу использовать email
модуль для создания электронной почты.
Мои идеи до сих пор были:
Вы сказали, что ваш скрипт «вызывает кучу функций», поэтому я предполагаю, что это функции Python, доступные из вашей программы. Я также предполагаю, что вы используете print
для генерации вывода во всех этих функциях. В этом случае вы можете просто заменить sys.stdout
на StringIO.StringIO
, который перехватит все, что вы пишете. Затем вы можете, наконец, вызвать метод .getValue
в вашем StringIO
, чтобы получить все, что было отправлено в выходной канал. Это также будет работать для внешних программ, использующих модуль подпроцесса, которые записывают в sys.stdout
.
Это дешевый способ. Я бы рекомендовал вам делать вывод, используя модуль logging
. У вас будет гораздо больше контроля над тем, как он выводит данные, и вам будет легче управлять им.
Захватить вывод довольно просто.
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()
Я изменил ответ 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'