0

我正在尝试捕获标准输出,然后在调用函数后对其进行解析。我通过 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() 怎么没有产生任何结果?

谢谢

4

1 回答 1

2

您刚刚完成了对 的写入stream,因此它的文件指针位于文件末尾。

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

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

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

一些旁注:

首先,几乎没有使用的充分理由readlines(),尤其是在这种情况下。文件已经是文件中行的可迭代;没有理由为了迭代它而创建相同行的列表。这将为您提供完全相同的结果:

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

……但更简单、更快,而且不会浪费内存。

其次,您的readstream功能比它需要的更复杂。通常,产生值的生成器比列表具有优势——它们让你的调用者在每个值可用时立即开始处理值,而不是等到它们全部完成,它们不会浪费内存来构建一个列表来迭代它等。但是在这种情况下,您已经通过调用来构建一个列表split,因此您不妨将其返回:

def readstream(s):
    c = s.getvalue()
    return c.split('\n')
于 2013-09-12T08:03:45.950 回答