Python 在像这样的文件上迭代和调用readline之间的区别

Python 在像这样的文件上迭代和调用readline之间的区别,python,io,iterator,subprocess,pipe,Python,Io,Iterator,Subprocess,Pipe,我一直认为在Python中对文件进行迭代相当于在循环中调用其readline方法,但今天我发现情况并非如此。具体来说,我有一个Popen'd进程pwhere list(itertools.takewhile(lambda x: x != "\n", p.stdout)) 挂起(可能是因为p等待输入;stdin和stdout都是到我的Python进程的管道),而下面的工作: list(itertools.takewhile(lambda x: x

我一直认为在Python中对文件进行迭代相当于在循环中调用其
readline
方法,但今天我发现情况并非如此。具体来说,我有一个
Popen
'd进程
p
where

list(itertools.takewhile(lambda x: x != "\n",
                         p.stdout))
挂起(可能是因为
p
等待输入;
stdin
stdout
都是到我的Python进程的管道),而下面的工作:

list(itertools.takewhile(lambda x: x != "\n",
                         iter(p.stdout.readline, "")))

有人能解释一下区别吗?

区别纯粹在于迭代的实现与
readline
方法。文件迭代读取块(默认情况下为8 KB),然后在使用缓冲区时将其拆分为行。另一方面,
readline
方法注意不要读取超过一行,这意味着逐字读取。分块读取效率更高,但这意味着不能在读取之间混合对文件执行其他操作。我们的期望是,当您在文件上迭代时,您的目的是按顺序读取所有行,而不会对其执行其他操作。
readline
方法不能做出这样的假设


正如Sven Marnach在对您的问题的评论中所暗示的那样,您可以使用
iter(f.readline,”)
获得一个迭代器,该迭代器从文件中读取行而不以性能为代价。

旁注:您可以使用
iter(f.readline,None)
,甚至
iter(f.readline,“\n”代替
fiter()
替换
takewhile()
。您看到的问题与缓冲有关:
文件。\uuuu iter\uuuu()
file.readline()
具有更大的缓冲能力,这也是为什么不能混合使用它们的原因。现在懒得研究细节并把它变成答案…@SvenMarnach:你的意思是
iter(f.readline,“”)
,但是是的,谢谢,我一直忘了:)我用
None
来模拟
而不是True
。很高兴看到你毕竟是人类,并不知道一切:-)你知道在CPython源代码中我在哪里可以找到文件迭代器的实现吗?在
对象/fileobject.c
中。文件对象是它们自己的迭代器,因此没有单独的类型
file.readline
file\u readline
,迭代是通过
file\u iternext
完成的。直接链接到源代码: