Um eine Lazy-Funktion zu schreiben, verwenden Sie einfach yield
:
def read_in_chunks(file_object, chunk_size=1024):
"""Lazy function (generator) to read a file piece by piece.
Default chunk size: 1k."""
while True:
data = file_object.read(chunk_size)
if not data:
break
yield data
with open('really_big_file.dat') as f:
for piece in read_in_chunks(f):
process_data(piece)
Eine andere Option wäre die Verwendung iter
und eine Hilfsfunktion:
f = open('really_big_file.dat')
def read1k():
return f.read(1024)
for piece in iter(read1k, ''):
process_data(piece)
Wenn die Datei zeilenbasiert ist, ist das Dateiobjekt bereits ein verzögerter Zeilengenerator:
for line in open('really_big_file.dat'):
process_data(line)
f = open('really_big_file.dat')
ist also nur ein Zeiger ohne Speicherverbrauch? (Ich meine, der verbrauchte Speicher ist unabhängig von der Dateigröße gleich?) Wie wirkt sich dies auf die Leistung aus, wenn ich urllib.readline () anstelle von f.readline () verwende?rb
wie @Tal Weiss erwähnt; und fehlendefile.close()
Aussage (könnte verwendet werdenwith open('really_big_file.dat', 'rb') as f:
, um dasselbe zu erreichen; siehe hier für eine andere prägnante Implementierung'rb'
wird nicht fehlen.'b'
seine Daten sehr wahrscheinlich beschädigt werden . Aus den Dokumenten -Python on Windows makes a distinction between text and binary files; [...] it’ll corrupt binary data like that in JPEG or EXE files. Be very careful to use binary mode when reading and writing such files.
Wenn Ihr Computer, Betriebssystem und Python 64-Bit sind , können Sie das mmap-Modul verwenden , um den Inhalt der Datei in den Speicher abzubilden und mit Indizes und Slices darauf zuzugreifen. Hier ein Beispiel aus der Dokumentation:
Wenn entweder Ihr Computer, Ihr Betriebssystem oder Python 32-Bit sind , kann das Zuordnen großer Dateien große Teile Ihres Adressraums reservieren und Ihr Speicherprogramm hungern lassen .
quelle
file.readlines()
Nimmt ein optionales Größenargument an, das sich der Anzahl der in den zurückgegebenen Zeilen gelesenen Zeilen annähert.quelle
.read()
nicht zu verwenden.readlines()
. Wenn die Datei binär ist, kommt es nicht zu Zeilenumbrüchen.Es gibt bereits viele gute Antworten, aber wenn sich Ihre gesamte Datei in einer einzelnen Zeile befindet und Sie dennoch "Zeilen" verarbeiten möchten (im Gegensatz zu Blöcken mit fester Größe), helfen Ihnen diese Antworten nicht weiter.
In 99% der Fälle ist es möglich, Dateien zeilenweise zu verarbeiten. Dann können Sie, wie in dieser Antwort vorgeschlagen , das Dateiobjekt selbst als Lazy Generator verwenden:
Allerdings bin ich einmal auf eine sehr sehr große (fast) einzeilige Datei gestoßen, in der das Zeilentrennzeichen eigentlich nicht
'\n'
aber war'|'
.'|'
in'\n'
vor der Verarbeitung kam ebenfalls nicht in Frage, da einige der Felder dieser CSV enthalten waren'\n'
( Freitext- Benutzereingabe).Für diese Art von Situationen habe ich das folgende Snippet erstellt:
Ich konnte es erfolgreich einsetzen, um mein Problem zu lösen. Es wurde ausgiebig mit verschiedenen Blockgrößen getestet.
Testsuite für diejenigen, die sich selbst überzeugen wollen.
quelle
UPDATE: Der Ansatz wird am besten unter https://stackoverflow.com/a/4566523/38592 erläutert
quelle
Weitere Informationen finden Sie in der offiziellen Dokumentation von Python unter https://docs.python.org/zh-cn/3/library/functions.html?#iter
Vielleicht ist diese Methode pythonischer:
quelle
Ich denke, wir können so schreiben:
quelle
Ich darf aufgrund meines schlechten Rufs keine Kommentare abgeben, aber die SilentGhosts-Lösung sollte mit file.readlines ([sizehint]) viel einfacher sein.
Python-Dateimethoden
edit: SilentGhost ist richtig, aber das sollte besser sein als:
quelle
Ich bin in einer ähnlichen Situation. Es ist nicht klar, ob Sie die Blockgröße in Bytes kennen. Normalerweise nicht, aber die Anzahl der erforderlichen Datensätze (Zeilen) ist bekannt:
Update : Danke nosklo. Hier ist was ich meinte. Es funktioniert fast, außer dass es eine Linie zwischen den Stücken verliert.
Hat der Trick ohne Zeilenverlust zu verlieren, sieht aber nicht sehr gut aus.
quelle
Dies ist eine elegante Lösung, um Zeile für Zeile zu verarbeiten:
Solange es keine Leerzeilen gibt.
quelle
open
bereits erhalten. Eine Datei ist bereits ein Iterator über ihre Zeilen.Sie können folgenden Code verwenden.
open () gibt ein Dateiobjekt zurück
Verwenden Sie dann os.stat, um die Größe zu ermitteln
quelle