Ich möchte viele Dateien behandeln, als ob sie alle eine Datei wären. Was ist der richtige phytonische Weg [Dateinamen] => [Dateiobjekte] => [Zeilen] mit Generatoren/nicht eine ganze Datei in den Speicher zu lesen?Was ist der pythischste Weg, um alle Zeilen mehrerer Dateien zu durchlaufen?
Wir alle wissen, der richtige Weg, um eine Datei zu öffnen:
with open("auth.log", "rb") as f:
print sum(f.readlines())
Und wir wissen, die richtige Art und Weise mehrere Iteratoren/Generatoren in einer lang zu verknüpfen:
>>> list(itertools.chain(range(3), range(3)))
[0, 1, 2, 0, 1, 2]
aber wie kann ich mehrere Dateien miteinander verknüpfen und die Kontextmanager beibehalten?
with open("auth.log", "rb") as f0:
with open("auth.log.1", "rb") as f1:
for line in itertools.chain(f0, f1):
do_stuff_with(line)
# f1 is now closed
# f0 is now closed
# gross
Ich konnte die Kontext-Manager ignorieren und so etwas tun, aber es fühlt sich nicht richtig:
files = itertools.chain(*(open(f, "rb") for f in file_names))
for line in files:
do_stuff_with(line)
Oder ist diese Art von dem, was für Async IO - PEP 3156 ist und ich muss nur an warte später auf die elegante Syntax?
Beachten Sie auch, dass 'files = itertools.chain (* (open (f," rb ") für f in file_names)) in diesem Zusammenhang definitiv nicht gut ist. Wenn Sie das Tupel entpacken, werden alle Ihre Dateien geöffnet, bevor Sie tatsächlich den Konstruktor "chain" eingeben. Sie sind besser dran mit 'itertools.chain.from_iterable (offen (fname, 'r') für fname in Dateinamen))' - In der Tat ist dies ein klassischer Grund, warum die 'from_iterable' Klassenmethode in der ersten existieren muss Ort :). – mgilson
@mgilson hatte keine Ahnung 'from_iterable' war eine Sache! Ich bin froh, dass mein Anwendungsfall ein Beispiel dafür ist, warum es nützlich ist. Ich versuchte herauszufinden, wie man die Lazy-Evaluierung ohne geschachtelte For-Schleifen richtig durchführen kann. Vielen Dank! –
Beachten Sie, dass selbst das 'from_iterable' nicht garantiert, dass alle Ihre Dateien geschlossen sind, wenn Sie mit der Iteration fertig sind, weil Sie nie wissen, wann' __del__' tatsächlich ausgeführt wird (obwohl ich ziemlich sicher bin, dass sie da sind) Cpython) ... – mgilson