Wenn Sie in Python entweder eine Datei öffnen, ohne sie aufzurufen close()
, oder die Datei schließen, aber nicht verwenden try
- finally
oder die with
Anweisung " ", ist dies ein Problem? Oder reicht es als Codierungspraxis aus, sich auf die Python-Garbage-Collection zu verlassen, um alle Dateien zu schließen? Zum Beispiel, wenn man dies tut:
for line in open("filename"):
# ... do stuff ...
... ist dies ein Problem, weil die Datei niemals geschlossen werden kann und eine Ausnahme auftreten kann, die verhindert, dass sie geschlossen wird? Oder wird es am Ende der for
Erklärung definitiv geschlossen, weil die Datei nicht mehr gültig ist?
python
file
garbage-collection
user553702
quelle
quelle
for
. Der Referenzzähler wird auf Null gesetzt, wodurch er automatisch geschlossen wird. Es werden jedoch nur Funktionen, Klassen und Module in Python definiert, keine anderen zusammengesetzten Anweisungen.for
Blöcken und Funktionen / Klassen / Modulen zusammen. Es ist viel einfacher als das: Objekte haben keine Bereiche, nur Namen. Es gibt keinen Namen, der auf dieses Objekt verweist, daher gibt es hier nichts, was im Geltungsbereich bleiben oder den Geltungsbereich verlassen könnte.for
Schleife ein Bereich zugeordnet ist, und erwähnt, dass die Datei aus einem ganz anderen Grund geschlossen wird. Es wird nicht auf die Bereiche in Python eingegangen, da dies hier nicht relevant ist.Antworten:
In Ihrem Beispiel wird nicht garantiert, dass die Datei geschlossen wird, bevor der Interpreter beendet wird. In aktuellen Versionen von CPython wird die Datei am Ende der for-Schleife geschlossen, da CPython die Referenzzählung als primären Speicherbereinigungsmechanismus verwendet. Dies ist jedoch ein Implementierungsdetail und kein Merkmal der Sprache. Andere Implementierungen von Python funktionieren garantiert nicht auf diese Weise. Zum Beispiel verwenden IronPython, PyPy und Jython keine Referenzzählung und schließen daher die Datei am Ende der Schleife nicht.
Es ist eine schlechte Praxis, sich auf die Garbage Collection-Implementierung von CPython zu verlassen, da dadurch Ihr Code weniger portabel wird. Wenn Sie CPython verwenden, treten möglicherweise keine Ressourcenlecks auf. Wenn Sie jedoch jemals zu einer Python-Implementierung wechseln, die keine Referenzzählung verwendet, müssen Sie den gesamten Code durchgehen und sicherstellen, dass alle Ihre Dateien ordnungsgemäß geschlossen sind.
Verwenden Sie für Ihr Beispiel:
quelle
with open() as f
die Datei nach Abschluss automatisch geschlossen?with
Anweisung bereitstellt, aber damit diese Magie funktioniert, muss das Objekt die speziellen Methoden haben,__enter__
und__exit__
in letzterem muss das Objekt dieclose
und alle anderen Aufräumarbeiten ausführen, die am ausgeführt werden müssen Ende derwith
Erklärung ...Einige Pythons schließen Dateien automatisch, wenn nicht mehr auf sie verwiesen wird, während andere dies nicht tun. Es liegt an den Betriebssystemen, Dateien zu schließen, wenn der Python-Interpreter beendet wird.
Selbst für die Pythons, die Dateien für Sie schließen, ist das Timing nicht garantiert: Es kann sofort oder Sekunden / Minuten / Stunden / Tage später sein.
Obwohl Sie möglicherweise keine Probleme mit dem von Ihnen verwendeten Python haben, ist es definitiv keine gute Praxis, Ihre Dateien offen zu lassen. Tatsächlich erhalten Sie in cpython 3 jetzt Warnungen, dass das System Dateien für Sie schließen musste, wenn Sie dies nicht getan haben.
Moral: Räumen Sie nach sich selbst auf. :) :)
quelle
Obwohl es in diesem speziellen Fall ziemlich sicher ist, ein solches Konstrukt zu verwenden, gibt es einige Vorbehalte, um eine solche Praxis zu verallgemeinern:
quelle
Die Datei wird mit Müll gesammelt und daher geschlossen. Der GC bestimmt, wann er geschlossen wird, nicht Sie. Dies ist offensichtlich keine empfohlene Vorgehensweise, da Sie möglicherweise das Limit für das Öffnen von Dateihandles erreichen, wenn Sie Dateien nicht schließen, sobald Sie sie nicht mehr verwenden. Was ist, wenn Sie in
for
Ihrer Schleife weitere Dateien öffnen und sie verweilen lassen?quelle
for
Anweisung erfasst - Sie müssen nicht auf den nächsten Speicherbereinigungslauf warten.Hallo, es ist sehr wichtig, den Dateideskriptor zu schließen, wenn Sie den Inhalt im selben Python-Skript verwenden möchten. Ich selbst merke heute nach so langem hektischem Debuggen. Der Grund dafür ist, dass Inhalte erst bearbeitet / entfernt / gespeichert werden, nachdem Sie Ihren Dateideskriptor geschlossen haben und Änderungen an der Datei betroffen sind!
Angenommen, Sie schreiben Inhalte in eine neue Datei und verwenden diese Datei (nicht fd) in einem anderen Shell-Befehl, der den Inhalt liest, ohne fd zu schließen. In dieser Situation erhalten Sie nicht wie erwartet Inhalte für den Shell-Befehl, und wenn Sie versuchen, Fehler zu beheben, können Sie den Fehler nicht leicht finden. Sie können auch mehr in meinem Blogeintrag http://magnificentzps.blogspot.in/2014/04/importance-of-closing-file-descriptor.html lesen
quelle
Während des E / A-Prozesses werden Daten gepuffert. Dies bedeutet, dass sie an einem temporären Speicherort gespeichert werden, bevor sie in die Datei geschrieben werden.
Python leert den Puffer nicht, dh schreibt Daten in die Datei, bis Sie sicher sind, dass Sie mit dem Schreiben fertig sind. Eine Möglichkeit, dies zu tun, besteht darin, die Datei zu schließen.
Wenn Sie in eine Datei schreiben, ohne sie zu schließen, gelangen die Daten nicht in die Zieldatei.
quelle