读取python中捕获的stdout中的行

时间:2013-09-12 07:51:51

标签: python python-2.7

我正在尝试捕获stdout,然后在调用函数后解析它。我是通过cStringIO.StringIO对象这样做的,但是readline调用没有产生任何结果。我创建了以下测试来向您展示发生了什么:

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

生成的输出为:

getvalue:
testing this stuff
more testing of this

readlines:
readstream:
testing this stuff
more testing of this

stream.readlines()怎么没有产生什么?

感谢

1 个答案:

答案 0 :(得分:2)

您刚刚写完stream,因此其文件指针位于文件的末尾。

readlines返回当前文件指针中的所有行,直到文件末尾。由于从文件末尾到文件末尾没有行,因此不返回任何行。

如果要将文件指针移回文件的开头,请使用seek方法:

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

一些附注:

首先,there is almost never a good reason to use readlines(),尤其不是在这种情况下。文件已经文件中可迭代的行;没有理由创建相同行的列表只是为了迭代它。这将给你完全相同的结果:

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

...但更简单,更快速,而且不浪费记忆。

其次,你的readstream函数比它需要的更复杂。通常情况下,生成值的生成器优于列表 - 它们让调用者在每个值都可用时立即开始处理值,而不是等到它们全部完成后,它们不会浪费内存构建列表只是为了迭代它等等。但在这种情况下,您已经通过调用split建立了一个列表,所以您也可以将其返回:

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