Reading lines in captured stdout in python
Question: I am trying to capture stdout and then parse it after calling a function. I am
doing so by means of a cStringIO.StringIO object but the readline call yields
nothing. I have created below test to show you what's happening:

    
    
    import cStringIO, sys
    
    def readstream(s):
        c = s.getvalue()
        for i in c.split('\n'):
            yield i
    
    old_stdout = sys.stdout
    stream = cStringIO.StringIO()
    sys.stdout = stream
    
    print ('testing this stuff')
    print ('more testing of this')
    
    sys.stdout = old_stdout
    
    print 'getvalue:'
    print stream.getvalue()
    
    print 'readlines:'
    for line in stream.readlines():
        print line
    
    print 'readstream:'
    for line in readstream(stream):
        print line
    

The generated output is:

    
    
    getvalue:
    testing this stuff
    more testing of this
    
    readlines:
    readstream:
    testing this stuff
    more testing of this
    

How is it that the stream.readlines() is yielding nothing?

thanks


Answer: You've just finished writing into `stream`, so its file pointer is at the end
of the file.

`readlines` returns all lines from the current file pointer until the end of
the file. Since there are no lines from the end of the file to the end of the
file, it returns no lines.

If you want to move the file pointer back to the start of the file, use the
[`seek`](http://docs.python.org/2/library/stdtypes.html#file.seek) method:

    
    
    print 'readlines:' # will print nothing
    stream.seek(0)
    for line in stream.readlines():
        print line
    

* * *

A few side notes:

First, [there is almost never a good reason to use
`readlines()`](http://stupidpythonideas.blogspot.com/2013/06/readlines-
considered-silly.html), and especially not in this case. A file is _already_
an iterable of the lines in the file; there's no reason to create a list of
the same lines just to iterate it. This will give you the exact same result:

    
    
    stream.seek(0)
    for line in stream:
        print line
    

… but simpler, faster, and without wasting memory.

Second, your `readstream` function is more complicated than it needs to be.
Normally, generators yielding values have advantages over lists—they let your
caller start working on the values as soon as each one is available instead of
waiting until they're all done, they don't waste memory building a list just
to iterate over it, etc. But in this case, you're already building a list by
calling `split`, so you might as well just return it:

    
    
    def readstream(s):
        c = s.getvalue()
        return c.split('\n')
    

