2009-04-15 10 views
4

Ich hoffe, ich habe die Frage richtig formuliert. Ich versuche mich zu zwingen, ein besserer Programmierer zu sein. Mit besser, ich meine effizient. Ich möchte ein Programm schreiben, um die Dateien in einem Verzeichnis zu identifizieren und jede Datei für die weitere Verarbeitung zu lesen. Nach einigen schlurfenden bekam ich dazu:Wie zu wissen, wann Ressourcen in Python verwalten

for file in os.listdir(dir): 
    y=open(dir+'\\'+file,'r').readlines() 
    for line in y: 
     pass 
    y.close() 

Es soll nicht überraschen, dass ich ein Attribut bekommen, da y eine Liste ist. Daran habe ich nicht gedacht, als ich das Snippet geschrieben habe.

ich darüber denke und habe Angst, dass ich fünf offene Dateien (es gibt fünf Dateien in dem Verzeichnis, das von dir angegeben.

Ich kann den Code beheben, damit es läuft und ich schließe ausdrücklich die Dateien nach dem Öffnen . sie ich bin gespannt, ob es nötig ist oder wenn Python behandelt die Datei in der nächsten Iteration der Schleife zu schließen wenn ja, dann nur ich muss schreiben:.

for file in os.listdir(dir): 
    y=open(dir+'\\'+file,'r').readlines() 
    for line in y: 
     pass 

ich vermute, ich, dass es (Python) umgehen kann Das ist der Grund, warum ich denke, dass dies so gehandhabt werden könnte, dass ich das Objekt/das Ding, auf das y verweist, geändert habe, wenn ich die zweite Iteration t starte Hier sind keine Speicherreferenzen mehr auf die Datei, die mit der readlines-Methode geöffnet und gelesen wurde.

+0

ich etwas fehlen muss, aber es ist eine Überraschung für mich, dass Sie einen Attribute, wenn y eine Liste ist. –

+0

Das OP bezieht sich auf die Zeile 'y.close()', glaube ich. –

+0

Sie können eine Liste nicht schließen, y ist eine Liste mit der readlines() -Methode - ich hoffe, Methode ist der richtige Name für was readlines ist. – PyNEwbie

Antwort

11

Python wird geöffnete Dateien schließen, wenn sie von Müll gesammelt werden, also können Sie es im Allgemeinen vergessen - besonders beim Lesen.

Das heißt, wenn Sie explizit schließen möchten, können Sie dies tun:

for file in os.listdir(dir): 
    f = open(dir+'\\'+file,'r') 
    y = f.readlines() 
    for line in y: 
     pass 
    f.close() 

Jedoch können wir dies sofort verbessern, weil in Python Sie über Datei-ähnliche Objekte direkt laufen kann:

for file in os.listdir(dir): 
    y = open(dir+'\\'+file,'r') 
    for line in y: 
     pass 
    y.close() 

schließlich in den letzten python gibt es die 'with' Aussage:

for file in os.listdir(dir): 
    with open(dir+'\\'+file,'r') as y: 
     for line in y: 
      pass 

Wenn der Block with endet, schließt Python die Datei für Sie und bereinigt sie.

(möchten Sie vielleicht auch für mehr pythonic Werkzeuge in os.path suchen für die Manipulation von Dateinamen und Verzeichnisse)

+0

für die Datei in os. listdir (dir): \t für Zeile in öffnen (dir + '\\' + Datei, 'r'): \t \t übergeben Ihr Vorschlag führte dazu. – PyNEwbie

+0

In Python 2.5 oder besser würde ich die 'with'-Anweisungsformulare bevorzugen, die die Absicht des Codes klar kommunizieren. – kquinn

+0

Yup. Beachten Sie, dass Sie einen __future__ Import durchführen müssen, um es in Python 2.5 zu erhalten. –

3

Sorgen Sie sich nicht über sie. Pythons Garbage Collector ist gut, und ich hatte nie ein Problem mit dem Schließen von Dateizeigern (zumindest für Leseoperationen).

Wenn Sie die Datei explizit schließen wollten, dann speichern Sie einfach die open() in einer Variablen, dann rufen readlines() auf, dass zum Beispiel ..

f = open("thefile.txt") 
all_lines = f.readlines() 
f.close() 

Oder Sie die with Anweisung verwenden können, die in Python 2.5 als from __future__ importieren und "richtig", fügte in Python 2.6 wurde hinzugefügt:

from __future__ import with_statement # for python 2.5, not required for >2.6 

with open("thefile.txt") as f: 
    print f.readlines() 

# or 

the_file = open("thefile.txt") 
with the_file as f: 
    print f.readlines() 

Die Datei wird automatisch am Ende der Sperre geschlossen.

..aber es gibt andere wichtigere Dinge in den Snippets, die Sie gepostet haben, hauptsächlich stilistische Dinge.

Versuchen Sie zunächst, das manuelle Erstellen von Pfaden mit String-Verkettung zu vermeiden. Das Modul os.path enthält viele Methoden, um dies auf eine zuverlässigere, plattformübergreifende Weise zu tun.

import os 
y = open(os.path.join(dir, file), 'r') 

Auch Sie werden mit zwei Variablennamen, dir und file - beide sind integrierte Funktionen. Pylint ist ein gutes Werkzeug, Dinge wie diese zu erkennen, in diesem Fall wäre es die Warnung geben:

[W0622] Redefining built-in 'file' 
+1

Dies war nützlich, danke. Meine Freunde denken, ich bin ein Genie, aber dann zeige ich ihnen, wie diese Website alles möglich macht. – PyNEwbie

Verwandte Themen