如何在Python中循环直到EOF?
我需要循环读取一个像文件一样的对象,直到到达文件的末尾,但我找不到一个“明显的方法”,这让我觉得我可能忽略了什么简单的东西。:-)
我有一个流(在这个例子中,它是一个StringIO对象,但我也对一般情况感兴趣),这个流以“<长度><数据>”的格式存储了不确定数量的记录,比如:
data = StringIO("\x07\x00\x00\x00foobar\x00\x04\x00\x00\x00baz\x00")
现在,我能想到的唯一清晰的读取方法是使用(我认为是)一个初始化的循环,这看起来有点不符合Python的风格:
len_name = data.read(4)
while len_name != "":
len_name = struct.unpack("<I", len_name)[0]
names.append(data.read(len_name))
len_name = data.read(4)
在像C这样的语言中,我只需把read(4)
放在while
的测试条件里,但当然这在Python中行不通。你有什么更好的方法来实现这个吗?
6 个回答
6
我更喜欢之前提到的基于迭代器的方案,把这个变成一个for循环。还有一种直接写的解决方案是Knuth的“半循环”方法。
while 1:
len_name = data.read(4)
if not len_name:
break
names.append(data.read(len_name))
你可以通过对比看到,这个方法很容易被提取成一个独立的生成器,然后用作for循环。
10
你知道怎么逐行读取一个文本文件吗?
for line in file_obj:
use(line)
你也可以用自己的生成器来做到这一点:
def read_blocks(file_obj, size):
while True:
data = file_obj.read(size)
if not data:
break
yield data
for block in read_blocks(file_obj, 4):
use(block)
另外,你可以看看:
27
你可以把使用 iter() 这个函数进行循环和一个哨兵值结合起来:
for block in iter(lambda: file_obj.read(4), ""):
use(block)