Reputation: 83250
I've got a python script that calls a bunch of functions, each of which writes output to stdout. Sometimes when I run it, I'd like to send the output in an e-mail (along with a generated file). I'd like to know how I can capture the output in memory so I can use the email
module to build the e-mail.
My ideas so far were:
Upvotes: 7
Views: 6179
Reputation: 36023
And I modified Gary Robinson's answer to make sure that stdout
is always restored, even if there's an exception:
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()
Upvotes: 3
Reputation: 141
I modified None's answer to make it a context manager:
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()
Usage:
with capture_stdout() as capture:
print 'Hello'
print 'Goodbye'
assert capture.result == 'Hello\nGoodbye\n'
Upvotes: 14
Reputation: 3933
It's pretty simple to capture output.
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()
Upvotes: 8
Reputation: 72755
You said that your script "calls a bunch of functions" so I'm assuming that they're python functions accessible from your program. I'm also assuming you're using print
to generate the output in all these functions. If that's the case, you can just replace sys.stdout
with a StringIO.StringIO
which will intercept all the stuff you're writing. Then you can finally call the .getValue
method on your StringIO
to get everything that has been sent to the output channel. This will also work for external programs using the subprocess module which write to sys.stdout
.
This is a cheap way. I'd recommend that you do your output using the logging
module. You'll have much more control over how it does it's output and you can control it more easily as well.
Upvotes: 4