Antworten:
Durchlaufen Sie die Datei, um Zeilen zu lesen:
with open('somefile') as openfileobject:
for line in openfileobject:
do_something()
Dateiobjekte sind iterierbar und ergeben bis EOF Linien. Wenn Sie das Dateiobjekt als iterable verwenden, wird ein Puffer verwendet, um performante Lesevorgänge sicherzustellen.
Sie können dasselbe mit dem stdin tun (keine Verwendung erforderlich raw_input():
import sys
for line in sys.stdin:
do_something()
Um das Bild zu vervollständigen, können binäre Lesevorgänge durchgeführt werden mit:
from functools import partial
with open('somefile', 'rb') as openfileobject:
for chunk in iter(partial(openfileobject.read, 1024), b''):
do_something()
Dabei chunkenthält die Datei bis zu 1024 Byte gleichzeitig. Die Iteration wird beendet, wenn openfileobject.read(1024)leere Byte-Zeichenfolgen zurückgegeben werden.
stdinlaufenden Prozess ... also hat es nie EOF, bis ich den Prozess beendet habe. Aber dann erreiche ich das "Ende bis jetzt" und bin festgefahren. Wie erkenne ich das und keinen Deadlock? Wenn keine neuen Zeilen vorhanden sind, hören Sie auf, die Dateien zu lesen (auch wenn kein EOF vorhanden ist, der in meinem Fall niemals vorhanden sein wird).
Sie können das C-Idiom in Python imitieren.
So lesen Sie einen Puffer bis zu einer max_sizeAnzahl von Bytes:
with open(filename, 'rb') as f:
while True:
buf = f.read(max_size)
if not buf:
break
process(buf)
Oder eine Textdatei Zeile für Zeile:
# warning -- not idiomatic Python! See below...
with open(filename, 'rb') as f:
while True:
line = f.readline()
if not line:
break
process(line)
Sie müssen while True / breakKonstrukt verwenden, da es in Python keinen anderen Eof-Test gibt als das Fehlen von Bytes, die von einem Lesevorgang zurückgegeben werden.
In C haben Sie möglicherweise:
while ((ch != '\n') && (ch != EOF)) {
// read the next ch and add to a buffer
// ..
}
In Python ist dies jedoch nicht möglich:
while (line = f.readline()):
# syntax error
da Zuweisungen in Ausdrücken in Python nicht zulässig sind (obwohl neuere Versionen von Python dies mithilfe von Zuweisungsausdrücken nachahmen können, siehe unten).
Es ist sicherlich mehr idiomatische in Python zu tun:
# THIS IS IDIOMATIC Python. Do this:
with open('somefile') as f:
for line in f:
process(line)
Update: Seit Python 3.8 können Sie auch Zuweisungsausdrücke verwenden :
while line := f.readline():
process(line)
readline()Methode einen Vorteil hat : Sie können eine feinkörnige Fehlerbehandlung wie das Fangen durchführen UnicodeDecodeError, was Sie mit der idiomatischen forIteration nicht tun können .
Die Python-Sprache zum Öffnen und zeilenweisen Lesen einer Datei lautet:
with open('filename') as f:
for line in f:
do_something(line)
Die Datei wird am Ende des obigen Codes automatisch geschlossen (das withKonstrukt kümmert sich darum).
Schließlich ist anzumerken, dass linedie nachfolgende Newline erhalten bleibt. Dies kann leicht entfernt werden mit:
line = line.rstrip()
for line in f.readlines(): ..., häufig vorgeschlagene Lösung.
Sie können das folgende Codefragment verwenden, um Zeile für Zeile bis zum Ende der Datei zu lesen
line = obj.readline()
while(line != ''):
# Do Something
line = obj.readline()
Zwar gibt es oben Vorschläge für "Python-Methode", aber wenn man wirklich eine auf EOF basierende Logik haben möchte, dann ist die Verwendung der Ausnahmebehandlung vermutlich die richtige Methode -
try:
line = raw_input()
... whatever needs to be done incase of no EOF ...
except EOFError:
... whatever needs to be done incase of EOF ...
Beispiel:
$ 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
Oder drücken Sie Ctrl-Zan einer raw_input()Eingabeaufforderung (Windows, Ctrl-ZLinux)
Sie können das folgende Code-Snippet verwenden. readlines () liest die gesamte Datei auf einmal ein und teilt sie zeilenweise auf.
line = obj.readlines()
Zusätzlich zu der großartigen Antwort von @ dawg gibt es die entsprechende Lösung mit dem Walross-Operator (Python> = 3.8):
with open(filename, 'rb') as f:
while buf := f.read(max_size):
process(buf)
linewird ein neues Zeilenzeichen angezeigt.