Смешивание file.readline() и file.next()

Я заметил какое-то странное поведение, которое сегодня играет с 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

Итак, общий вопрос здесь , что происходит под капотом, который вызывает эту ошибку?

Некоторые вопросы, на которые можно получить ответы, но я хотел бы услышать ответ, если нет:

  • В чем разница между next() и readline()?
  • Когда я делаю for f in file:, какую функцию я вызываю (и это имеет значение)?
  • Почему я могу вызвать next() после readline(), но не наоборот?

Спасибо заранее,

Я не думаю, что это важно, но если это зависит от версии, я нахожусь на Python 2.7.6 для Windows

Ответ 1

Согласно Документ Python (акцент мой)

Файловый объект - это его собственный итератор, например, iter (f) возвращает f (если f не закрыто). Когда файл используется как итератор, обычно в цикле for (например, для строки в f: print line.strip()), метод next() вызывается повторно. Этот метод возвращает следующую строку ввода или вызывает StopIteration, когда EOF попадает, когда файл открыт для чтения (поведение undefined, когда файл открыт для записи). Чтобы сделать цикл for наиболее эффективным способом петли по строкам файла (очень обычная операция), метод next() использует скрытый буфер чтения. Как следствие использования буфера с чтением, объединение next() с другими файловыми методами (например, readline()) не работает правильно. Однако использование функции поиска() для перестановки файла в абсолютную позицию приведет к сбросу буфера чтения вперед.

Метод next читает больше, что необходимо по соображениям эффективности. Это нарушает readline. Поэтому ответы

  • next быстрее из-за чтения вперед
  • for s in f: использовать next
  • перед вызовом next, readline использует стандартное медленное чтение файла, поэтому проблем нет.