2009-10-05 15 views

Antwort

94

Die close Methode muss auf dem Ergebnis von urllib.urlopen, nicht auf dem sich urllib Modul aufgerufen werden, wie Sie denken (wie Sie urllib.close erwähnen - was nicht existiert).

der beste Ansatz: Statt x = urllib.urlopen(u) usw., zu verwenden:

import contextlib 

with contextlib.closing(urllib.urlopen(u)) as x: 
    ...use x at will here... 

Die with Anweisung und der closing Kontext-Manager, kann die ordnungsgemäße Schließung gewährleistet auch von Ausnahmen in Gegenwart.

+8

Wie wäre es mit etwas wie 'data = urllib2.urlopen ('url') .lesen()' –

+13

In Python 3 wurde die direkte Unterstützung für die with-Anweisung hinzugefügt. mit urllib.urlopen (u) als x: ... –

3

Streng genommen ist dies der Fall. Aber in der Praxis, sobald (if) urllib den Geltungsbereich verlässt, wird die Verbindung vom automatischen Garbage Collector geschlossen.

+10

Dies gilt für einige Implementierungen von Python, aber die Python-Sprache garantiert nicht, dass das Schließen stattfindet, sobald das Objekt den Gültigkeitsbereich verlässt. vgl. jython –

+1

@gnibbler Der Autor dieser Antwort sagt nicht, dass es passieren wird * sobald * nur, dass es passieren wird. –

+2

@Piotr, aber vielleicht stürzt das Programm ab, wenn ich eine Schleife öffne URLs und der GC ernten sie nicht schnell genug. Es ist eine ziemlich schlampige Art, Dinge zu tun und gehört nicht in den Produktionscode. –

11

Wie @Peter sagt, können geöffnete Out-of-Scope-URLs für die Garbage Collection zugelassen werden.

jedoch auch beachten, dass urllib.py definiert:

def __del__(self): 
     self.close() 

Das bedeutet, dass , wenn der Referenzzähler für diese Instanz Null erreicht, seine __del__ Methode aufgerufen wird, und damit seine close Methoden wie aufgerufen werden Gut. Der "normale" Weg für die Referenzzählung, um Null zu erreichen, besteht darin, die Instanz einfach außerhalb des Gültigkeitsbereichs zu lassen, aber es gibt nichts, was Sie streng von einer expliziten del x früh abhält (jedoch ruft sie nicht direkt __del__ auf, sondern dekrementiert nur die Referenzzählung) einzeln).

Es ist sicherlich gut Stil explizit auf Ihre Ressourcen schließen - vor allem, wenn die Anwendung das Risiko der Verwendung von zu viel der Ressourcen läuft - aber Python wird automatisch für Sie aufzuräumen, wenn Sie etwas nicht tun, lustig wie Pflegen von (zirkularen?) Verweisen auf Instanzen, die Sie nicht mehr benötigen.

+2

Es ist jedoch möglich, den Garbage Collector zu überrollen - ich hatte Fälle, in denen ich Dateizugriffsnummern schneller als sie sie [aber wo ein explizite 'gc.collect() 'call, oder ein' close() ', räumte alles auf]. –

Verwandte Themen