2012-04-21 1 views
38

У меня есть проблема, чтобы понять итерацию на файл, Здесь я иду на то, что я печатаю на переводчике и результат:Итерация на файл с помощью Python

>>> f = open('baby1990.html', 'rU') 
>>> for line in f.readlines(): 
>>> print(line) 

>>> ... 
>>> ... all the lines from the file appear here 
>>> ... 

Когда я пытаюсь перебирать на том же открыта файл снова, я ничего не получил !!!!

>>> f = open('baby1990.html', 'rU') 
>>> for line in f.readlines(): 
>>> print(line) 
>>> 
>>> 

Нет никакого вывода, чтобы решить эту проблему. Я должен закрыть() файл и открыть его снова для чтения !! Это нормальное поведение?

ответ

61

Да, это нормальное поведение. Вы в основном читаете в конце файла в первый раз (вы можете сортировать его как чтение ленты), поэтому вы не можете читать дальше, если вы не сбросите его, либо используя f.seek(0), чтобы переместить в начало файл, или закрыть его, а затем снова открыть его, который начнется с начала файла.

Если вы предпочитаете использовать синтаксис with, который автоматически закроет файл для вас.

например,

with open('baby1990.html', 'rU') as f: 
    for line in f: 
    print line 

раз этот блок завершит выполнение, файл будет автоматически закрыт для вас, чтобы вы могли выполнить этот блок несколько раз без явного закрытия файла самостоятельно и прочитать файл таким образом снова.

+0

OP хочет помочь понять, что происходит, когда объект файла потребляется. –

+0

Я только что добавил эту часть объяснения. – Levon

+1

Нет смысла читать файл дважды, если вы используете 'readlines()'. –

1

Конечно. Это нормальное и нормальное поведение. Вместо закрытия и повторного открытия вы можете сделать rewind файл.

+0

Это не полезно для пользователя, который не знаком с понятием считывания указателя – scubbo

8

Файл является буфером. Когда вы читаете из буфера, потребляемая вами часть (позиция чтения сдвигается вперед). Когда вы читаете весь файл, позиция чтения находится в EOF, поэтому он ничего не возвращает, потому что читать нечего.

Если у вас есть, по какой-то причине, сброс положения чтения на объект файла, вы можете сделать:

f.seek(0) 
13

Как объект файла считывает файл, он использует указатель, чтобы отслеживать, где это. Если вы прочитаете часть файла, а затем вернитесь к нему позже, он поднимется туда, где вы остановились. Если вы прочитаете весь файл и вернетесь к тому же файловому объекту, это будет похоже на чтение пустого файла, потому что указатель находится в конце файла, и читать его нечего. Вы можете использовать file.tell(), чтобы увидеть, где в файле указатель, и file.seek, чтобы установить указатель. Например:

>>> file = open('myfile.txt') 
>>> file.tell() 
0 
>>> file.readline() 
'one\n' 
>>> file.tell() 
4L 
>>> file.readline() 
'2\n' 
>>> file.tell() 
6L 
>>> file.seek(4) 
>>> file.readline() 
'2\n' 

Кроме того, вы должны знать, что 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