混合使用file.readline()和file.next()

15 投票
1 回答
7585 浏览
提问于 2025-04-17 20:49

今天我在玩 next()readline() 的时候,发现了一些奇怪的情况。看起来这两个函数的结果是一样的(这也是我预期的)。不过,当我把它们混在一起用的时候,出现了一个 ValueError 的错误。以下是我做的事情:

>>> f = open("text.txt", 'r')
>>> f.readline()
'line 0\n'
>>> f.readline()
'line 1\n'
>>> f.readline()
'line 2\n'
>>> f.next()
'line 3\n'
>>> f.next()
'line 4\n'
>>> f.readline()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Mixing iteration and read methods would lose data
>>>
>>> f = open("text.txt", 'r')
>>> f.next()
'line 0\n'
>>> f.next()
'line 1\n'
>>> f.next()
'line 2\n'
>>> f.readline()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Mixing iteration and read methods would lose data

所以我想问的主要问题是到底发生了什么,导致了这个错误?

还有一些可能会一起解答的问题,但如果没有解答,我也想听听:

  1. next()readline() 有什么区别?
  2. 当我使用 for f in file: 时,我调用的是哪个函数(这重要吗)?
  3. 为什么我可以在 readline() 之后调用 next(),但反过来就不行?

提前谢谢你们,

我觉得这可能无关紧要,但如果这和版本有关,我用的是 Windows 上的 Python 2.7.6

1 个回答

22

根据Python的文档(强调是我自己的)

文件对象本身就是一个迭代器,比如说用iter(f)可以得到f(除非f已经关闭)。当文件作为迭代器使用时,通常是在for循环中(例如,for line in f: print line.strip()),next()方法会被反复调用。这个方法会返回下一行内容,或者在文件读取到末尾时抛出StopIteration(当文件是以写入模式打开时,行为就不确定了)。为了让for循环成为处理文件行的最有效方式(这是一种非常常见的操作),next()方法使用了一个隐藏的预读缓冲区。由于使用了预读缓冲区,结合next()和其他文件方法(像readline())时可能会出现问题。不过,使用seek()将文件重新定位到一个绝对位置会清空预读缓冲区。

next方法为了效率会读取比实际需要的更多内容。这会影响readline的正常工作。所以答案是:

  1. next因为预读而更快
  2. for s in f:使用next
  3. 在调用next之前,readline使用的是标准的慢速读取,所以没有问题。

撰写回答