Python 生成器和文件对象

use*_*298 4 python

我有一个关于生成器和文件对象的问题。

如果我写代码

def iter(ls):
    count=0
    for k in ls:
        if count==2:
            break
        count+=1
    for k in ls:
        yield k

test=[1,2,3,4]

k=iter(test)
for i in k:
    print i
Run Code Online (Sandbox Code Playgroud)

然后输出是

1 2 3 4

是的,我可以理解这一点,因为这段代码中的 break 语句不会影响下面的 yield 语句。

但是如果我对文件做类似的事情,在这种情况下,我会创建一个“数据”文件并写入

1
2
3
4
Run Code Online (Sandbox Code Playgroud)

如果我只改变线路

test=[1,2,3,4]  ?  test=open("data","r")
Run Code Online (Sandbox Code Playgroud)

那么结果是

4

这意味着 break 语句会以某种方式影响,因此包含“yield”的 for 循环中的生成器与之前的情况不同。

这种差异的原因是什么?

Ana*_*mar 5

是的,因为文件对象还存储它当前读取的位置。因此,当您尝试再次遍历文件对象(不做.seek())时,它将从下一行(您离开的地方)开始。那是在打开一个文件并对其进行一次迭代之后,如果您尝试再次对其进行迭代(不执行.seek()),它不会产生任何结果,因为在第一次迭代中,光标位于文件末尾并且什么都没有否则阅读。例子 -

我的 a.txt -

1
2
3
4
Run Code Online (Sandbox Code Playgroud)

代码 -

>>> for i in f:
...     print(i)
...
1

2

3

4
>>> for i in f:
...     print(i)
...
>>>
Run Code Online (Sandbox Code Playgroud)

——

如上所示,如果要将文件光标移动到文件的开头,则必须使用file.seek(0), 0 表示移动起始位置。