Iteracja na pliku za pomocą Pythona

Mam problem ze zrozumieniem iteracji na pliku, tu wchodzę na to co wpisuję na interpreterze i wynik:

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

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

Kiedy próbuję ponownie iterować na tym samym otwartym pliku, nie mam nic!!!!

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

W ogóle nie ma wyjścia, aby to rozwiązać, muszę zamknąć () plik, a następnie otworzyć go ponownie do czytania!! Czy to normalne zachowanie?

Author: Tshepang, 2012-04-21

4 answers

Tak, to normalne zachowanie. Zasadniczo czytasz do końca pliku za pierwszym razem (możesz go sobie wyobrazić jako czytającą taśmę), więc nie możesz odczytać z niego więcej, chyba że zresetujesz go, używając f.seek(0), Aby zmienić położenie na początek pliku, lub zamknąć go, a następnie otworzyć go ponownie, Co rozpocznie się od początku pliku.

Jeśli wolisz, możesz użyć składni with, która automatycznie zamknie plik za Ciebie.

Np.,

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

Once blok ten jest gotowy do wykonania, plik jest automatycznie zamykany dla ciebie, więc możesz wykonywać ten blok wielokrotnie bez jawnego zamykania pliku i odczytywać plik w ten sposób od nowa.

 67
Author: Levon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-21 12:50:06

Gdy obiekt file odczytuje plik, używa wskaźnika do śledzenia jego położenia. Jeśli przeczytasz część pliku, a następnie wróć do niego później, rozpocznie się tam, gdzie skończyłeś. Jeśli przeczytasz cały plik i wrócisz do tego samego obiektu file, będzie to jak czytanie pustego pliku, ponieważ wskaźnik znajduje się na końcu pliku i nie ma już nic do przeczytania. Możesz użyć file.tell(), aby zobaczyć, gdzie w pliku znajduje się wskaźnik i file.seek, aby ustawić wskaźnik. Na przykład:

>>> 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'

Także Ty powinieneś wiedzieć, że file.readlines() odczytuje cały plik i zapisuje go jako listę. Warto wiedzieć, bo można zastąpić:

for line in file.readlines():
    #do stuff
file.seek(0)
for line in file.readlines():
    #do more stuff

Z:

lines = file.readlines()
for each_line in lines:
    #do stuff
for each_line in lines:
    #do more stuff

Możesz również iterować nad plikiem, po jednej linii na raz, bez trzymania całego pliku w pamięci (może to być bardzo przydatne dla bardzo dużych plików), wykonując:

for line in file:
    #do stuff
 13
Author: Bi Rico,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-21 05:45:40

Obiekt file jest buforem . Podczas odczytu z bufora odczytana część jest zużywana (pozycja odczytu jest przesunięta do przodu). Kiedy czytasz cały plik, pozycja odczytu znajduje się w EOF, więc nic nie zwraca, ponieważ nie ma nic do odczytania.

Jeśli z jakiegoś powodu musisz zresetować pozycję odczytu w obiekcie file, możesz to zrobić:

f.seek(0)
 8
Author: Joel Cornett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-21 01:04:34

Oczywiście. To normalne i zdrowe zachowanie. Zamiast zamykać i ponownie otwierać, możesz rewind plik.

 1
Author: ch3ka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-21 01:02:36