Odpowiedzi:
Zapętl plik, aby odczytać linie:
with open('somefile') as openfileobject:
for line in openfileobject:
do_something()
Obiekty plików są iterowalne i dają linie do EOF. Użycie obiektu pliku jako elementu iteracyjnego wykorzystuje bufor, aby zapewnić wydajne odczyty.
Możesz zrobić to samo ze stdin (nie musisz używać raw_input()
:
import sys
for line in sys.stdin:
do_something()
Aby uzupełnić obraz, odczyty binarne można wykonać za pomocą:
from functools import partial
with open('somefile', 'rb') as openfileobject:
for chunk in iter(partial(openfileobject.read, 1024), b''):
do_something()
gdzie chunk
będzie zawierał do 1024 bajtów naraz z pliku, a iteracja zostanie zatrzymana, gdy openfileobject.read(1024)
zacznie zwracać puste ciągi bajtów.
stdin
uruchomionego procesu ... więc nigdy nie ma EOF, dopóki nie zabiję procesu. Ale potem dochodzę do „końca do teraz” i wpadam w impas. Jak to wykryć, a nie zakleszczenie? Na przykład, jeśli nie ma nowych linii, przestań czytać pliki (nawet jeśli nie ma EOF, który w moim przypadku nigdy nie będzie istniał).
Możesz naśladować idiom C w Pythonie.
Aby odczytać bufor o maksymalnej max_size
liczbie bajtów, możesz to zrobić:
with open(filename, 'rb') as f:
while True:
buf = f.read(max_size)
if not buf:
break
process(buf)
Lub plik tekstowy wiersz po wierszu:
# warning -- not idiomatic Python! See below...
with open(filename, 'rb') as f:
while True:
line = f.readline()
if not line:
break
process(line)
Musisz użyć while True / break
konstrukcji, ponieważ w Pythonie nie ma testu eof poza brakiem bajtów zwróconych z odczytu.
W C możesz mieć:
while ((ch != '\n') && (ch != EOF)) {
// read the next ch and add to a buffer
// ..
}
Jednak nie możesz tego mieć w Pythonie:
while (line = f.readline()):
# syntax error
ponieważ przypisania nie są dozwolone w wyrażeniach w Pythonie (chociaż najnowsze wersje Pythona mogą to naśladować za pomocą wyrażeń przypisania, patrz poniżej).
Z pewnością w Pythonie jest to bardziej idiomatyczne:
# THIS IS IDIOMATIC Python. Do this:
with open('somefile') as f:
for line in f:
process(line)
Aktualizacja: od Pythona 3.8 możesz także używać wyrażeń przypisania :
while line := f.readline():
process(line)
readline()
: możesz wykonać drobnoziarnistą obsługę błędów, taką jak wyłapywanie UnicodeDecodeError
, czego nie można zrobić z idiomatyczną for
iteracją.
Idiom Pythona do otwierania pliku i czytania go wiersz po wierszu to:
with open('filename') as f:
for line in f:
do_something(line)
Plik zostanie automatycznie zamknięty na końcu powyższego kodu ( with
zajmuje się tym konstrukcja).
Na koniec warto zauważyć, że line
zachowa końcowy znak nowej linii. Można to łatwo usunąć za pomocą:
line = line.rstrip()
for line in f.readlines(): ...
, powszechnie sugerowane rozwiązanie.
Możesz użyć poniższego fragmentu kodu, aby czytać wiersz po wierszu, aż do końca pliku
line = obj.readline()
while(line != ''):
# Do Something
line = obj.readline()
Chociaż powyżej są sugestie dotyczące "robienia tego w Pythonie", jeśli naprawdę chce się mieć logikę opartą na EOF, przypuszczam, że użycie obsługi wyjątków jest sposobem na zrobienie tego -
try:
line = raw_input()
... whatever needs to be done incase of no EOF ...
except EOFError:
... whatever needs to be done incase of EOF ...
Przykład:
$ echo test | python -c "while True: print raw_input()"
test
Traceback (most recent call last):
File "<string>", line 1, in <module>
EOFError: EOF when reading a line
Lub naciśnij Ctrl-Zpo wyświetleniu raw_input()
monitu (Windows, Ctrl-ZLinux)
Możesz użyć następującego fragmentu kodu. readlines () czyta cały plik naraz i dzieli go liniami.
line = obj.readlines()
Oprócz świetnej odpowiedzi @ dawg, równoważne rozwiązanie wykorzystujące operator morsa (Python> = 3,8):
with open(filename, 'rb') as f:
while buf := f.read(max_size):
process(buf)
line
końcu pojawi się znak nowej linii.