W przypadku ćwiczenia, które wykonuję, próbuję dwukrotnie odczytać zawartość danego pliku read()
metodą. O dziwo, kiedy wywołuję to po raz drugi, nie zwraca zawartości pliku jako ciągu?
Oto kod
f = f.open()
# get the year
match = re.search(r'Popularity in (\d+)', f.read())
if match:
print match.group(1)
# get all the names
matches = re.findall(r'<td>(\d+)</td><td>(\w+)</td><td>(\w+)</td>', f.read())
if matches:
# matches is always None
Oczywiście wiem, że to nie jest najbardziej efektywny ani najlepszy sposób, nie o to tutaj chodzi. Chodzi o to, dlaczego nie mogę zadzwonić read()
dwa razy? Czy muszę zresetować uchwyt pliku? Lub zamknij / ponownie otwórz plik, aby to zrobić?
Odpowiedzi:
Wywołanie
read()
czyta cały plik i pozostawia kursor odczytu na końcu pliku (bez niczego więcej do przeczytania). Jeśli szukasz czytać pewną liczbę wierszy w danym momencie można użyćreadline()
,readlines()
lub iterację liniachfor line in handle:
.Aby odpowiedzieć bezpośrednio na twoje pytanie, po przeczytaniu pliku
read()
możesz użyć,seek(0)
aby przywrócić kursor odczytu na początek pliku (dokumenty są tutaj ). Jeśli wiesz, że plik nie będzie zbyt duży, możesz również zapisaćread()
wynik do zmiennej, używając jej w swoich wyrażeniach findall.Ps. Nie zapomnij zamknąć pliku, gdy skończysz;)
źródło
with
.tak, jak wyżej ...
napiszę tylko przykład:
źródło
Każdy, kto do tej pory odpowiedział na to pytanie, ma całkowitą rację -
read()
przechodzi przez plik, więc po wywołaniu go nie można go ponownie wywołać.Dodam, że w twoim konkretnym przypadku nie musisz szukać początku ani ponownie otwierać pliku, możesz po prostu zapisać przeczytany tekst w zmiennej lokalnej i użyć go dwukrotnie, lub tyle razy, ile chcesz, w swoim programie:
źródło
from pathlib import Path; text = Path(filename).read_text()
Wskaźnik odczytu przesuwa się za ostatnim odczytanym bajtem / znakiem. Użyj
seek()
metody, aby przewinąć wskaźnik odczytu do początku.źródło
Każdy otwarty plik ma przypisaną pozycję.
Kiedy czytasz (), czytasz z tej pozycji. Na przykład
read(10)
czyta pierwsze 10 bajtów z nowo otwartego pliku, a następnie kolejnyread(10)
czyta następne 10 bajtów.read()
bez argumentów odczytuje całą zawartość pliku, pozostawiając pozycję pliku na końcu pliku. Następnym razem, gdy zadzwonisz,read()
nie ma nic do czytania.Możesz użyć,
seek
aby przesunąć pozycję pliku. Lub prawdopodobnie lepiej w twoim przypadku byłoby zrobić jednoread()
i zachować wynik dla obu wyszukiwań.źródło
read()
konsumuje . Tak więc, można przywrócić plik lub szukać na początku przed ponownym czytaniu. Lub, jeśli pasuje do twojego zadania, możesz użyćread(n)
do zużywania tylkon
bajtów.źródło
Zawsze uważam, że metoda czytania jest czymś w rodzaju spaceru ciemną uliczką. Schodzisz trochę w dół i zatrzymujesz się, ale jeśli nie liczysz kroków, nie jesteś pewien, jak daleko jesteś. Seek daje rozwiązanie poprzez zmianę pozycji, drugą opcją jest Tell, która zwraca pozycję wzdłuż pliku. Może to być plik API Pythona, który może łączyć odczyt i wyszukiwanie w read_from (pozycja, bajty), aby było to prostsze - do tego czasu powinieneś przeczytać tę stronę .
źródło