在Python中的同一进程中捕获stdout

dan*_*ben 6 python stream

我有一个调用一堆函数的python脚本,每个函数都将输出写入stdout.有时当我运行它时,我想通过电子邮件发送输出(以及生成的文件).我想知道如何捕获内存中的输出,以便我可以使用该email模块来构建电子邮件.

到目前为止我的想法是:

  • 使用内存映射文件(但似乎我必须为此保留磁盘空间,我不知道输出会有多长)
  • 绕过所有这一切并将输出传递给sendmail(但如果我还想附加文件,这可能很难)

Gar*_*son 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()
Run Code Online (Sandbox Code Playgroud)

用法:

with capture_stdout() as capture:
    print 'Hello'
    print 'Goodbye'
assert capture.result == 'Hello\nGoodbye\n'
Run Code Online (Sandbox Code Playgroud)


Non*_*one 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()
Run Code Online (Sandbox Code Playgroud)


Nou*_*him 4

你说你的脚本“调用了一堆函数”,所以我假设它们是可以从你的程序访问的Python函数。我还假设您正在使用print所有这些函数来生成输出。如果是这种情况,您只需替换sys.stdout为 aStringIO.StringIO即可拦截您正在编写的所有内容。然后您最终可以调用.getValue您的方法StringIO来获取已发送到输出通道的所有内容。这也适用于使用写入 .subprocess 模块的外部程序sys.stdout

这是一种廉价的方法。我建议您使用该logging模块进行输出。您将可以更好地控制它的输出方式,并且也可以更轻松地控制它。