在Python中捕获同一进程的stdout
我有一个Python脚本,它会调用很多函数,每个函数都会把结果输出到标准输出(也就是屏幕上)。有时候我运行这个脚本的时候,希望把这些输出内容通过电子邮件发送出去,同时还想附上一个生成的文件。我想知道怎么能把这些输出内容先存到内存里,这样我就可以用email
模块来构建电子邮件。
到目前为止,我的想法有:
- 使用内存映射文件(但这似乎需要在硬盘上预留空间,而我不知道输出内容会有多长)
- 绕过这些步骤,直接把输出通过管道发送到sendmail(但如果我还想附加文件,这可能会比较麻烦)
4 个回答
8
捕获输出其实很简单。
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()
14
我把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'
4
你提到你的脚本“调用了一堆函数”,所以我猜这些函数是你程序里可以用的Python函数。我还猜测你在这些函数里用print
来输出结果。如果是这样的话,你可以把sys.stdout
换成StringIO.StringIO
,这样就能拦截你写的所有内容。然后你可以调用StringIO
的.getValue
方法,获取所有发送到输出通道的内容。这种方法也适用于使用subprocess模块的外部程序,它们会写入sys.stdout
。
这是一种简单的方法。不过我建议你使用logging
模块来输出内容。这样你会对输出的方式有更多的控制,而且管理起来也更方便。