我正在尝试捕获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()怎么没有产生什么?
感谢
答案 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')