我有一个调用一堆函数的python脚本,每个函数都将输出写入stdout。有时当我运行它时,我想通过电子邮件发送输出(以及生成的文件)。我想知道如何捕获内存中的输出,以便我可以使用email
模块来构建电子邮件。
到目前为止我的想法是:
答案 0 :(得分:13)
我修改了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'
答案 1 :(得分:7)
捕获输出非常简单。
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()
答案 2 :(得分:3)
你说你的脚本“调用了很多函数”所以我假设它们是你的程序可以访问的python函数。我还假设您正在使用print
在所有这些函数中生成输出。如果是这种情况,您只需将sys.stdout
替换为StringIO.StringIO
即可拦截您正在编写的所有内容。然后,您最终可以调用.getValue
上的StringIO
方法,以获取已发送到输出通道的所有内容。这也适用于使用写入sys.stdout
。
这是一种廉价的方式。我建议您使用logging
模块进行输出。您可以更好地控制它的输出方式,您也可以更轻松地控制它。
答案 3 :(得分:1)
我修改了Gary Robinson的答案,以确保stdout
总是得到恢复,即使有异常:
import sys, StringIO, contextlib
class Data(object):
pass
@contextlib.contextmanager
def capture_stdout():
old = sys.stdout
capturer = StringIO.StringIO()
data = Data()
try:
sys.stdout = capturer
yield data
finally:
sys.stdout = old
data.result = capturer.getvalue()