Iterating on a file doesn't work the second time [duplicate]
Повторение файла не работает во второй раз
У меня проблема с повторением файла. Вот что я ввожу в интерпретаторе и результат:
>>> f = open('baby1990.html', 'rU') >>> for line in f.readlines(): ... print(line) ... # ... all the lines from the file appear here ...
Когда я пытаюсь выполнить итерацию по тому же открытому файлу снова, я ничего не получаю!
>>> for line in f.readlines(): ... print(line) ... >>>
Вывода вообще нет. Чтобы решить эту проблему, я должен close() файл, а затем снова открыть его для чтения! Это нормальное поведение?
Переведено автоматически
Ответ 1
Да, это нормальное поведение. В основном вы читаете до конца файла в первый раз (вы можете представить это как чтение ленты), поэтому вы не сможете читать из него больше, пока не сбросите его, либо используя f.seek(0) для перемещения в начало файла, либо закрыв его, а затем снова открыв, что начнется с начала файла.
Если вы предпочитаете, вы можете использовать with синтаксис вместо этого, который автоматически закроет файл для вас.
например,
withopen('baby1990.html', 'rU') as f: for line in f: print line
после завершения выполнения этого блока файл автоматически закрывается для вас, так что вы можете выполнить этот блок повторно, не закрывая файл явно самостоятельно, и прочитать файл таким образом снова.
Ответ 2
Когда объект file считывает файл, он использует указатель, чтобы отслеживать, где он находится. Если вы прочитаете часть файла, а затем вернетесь к нему позже, он продолжит с того места, на котором вы остановились. Если вы прочитаете весь файл целиком и вернетесь к тому же файловому объекту, это будет похоже на чтение пустого файла, потому что указатель находится в конце файла и читать больше нечего. Вы можете использовать file.tell(), чтобы увидеть, где в файле находится указатель, и file.seek установить указатель. Например:
Кроме того, вы должны знать, что file.readlines() считывает весь файл и сохраняет его в виде списка. Это полезно знать, потому что вы можете заменить:
for line in file.readlines(): #do stuff file.seek(0) for line in file.readlines(): #do more stuff
с:
lines = file.readlines() for each_line in lines: #do stuff for each_line in lines: #do more stuff
Вы также можете выполнять повторное выполнение файла по одной строке за раз, не удерживая весь файл в памяти (это может быть очень полезно для очень больших файлов), выполнив:
for line in file: #do stuff
Ответ 3
Файловый объект является буфером. При чтении из буфера используется та часть, которую вы читаете (позиция чтения смещается вперед). Когда вы читаете весь файл, позиция чтения находится в конце файла (EOF), поэтому он ничего не возвращает, потому что читать больше нечего.
Если вам по какой-либо причине необходимо сбросить позицию чтения для файлового объекта, вы можете сделать:
f.seek(0)
Ответ 4
Конечно. Это нормальное поведение. Вместо закрытия и повторного открытия вы могли бы rewind открыть файл.