2013-03-14 13 views
8

Ich verstehe, dass Python nicht die Reihenfolge der Zerstörung von Objekten am Ende des Programms garantiert, oder sogar, dass es passieren wird.Warum zerstört Python Klassenvariablen vor Objekten?

So verstehe ich, dass eine Klasse Destruktor kann nicht auf globale Variablen, einschließlich anderer Module verlassen.

Aber ich hätte gedacht, dass Objekte der Klasse zerstört werden müssten, bevor die Klasse zerstört wird. Offensichtlich nicht:

class A(object): 
    count = 0 
    def __init__(self): 
     A.count += 1 
     print 'Creating object, there are now', A.count 
    def __del__(self): 
     A.count -= 1 
     print 'Destroying object, there are now', A.count 

a1 = A() 
a2 = A() 

auf Windows 7 x64 Python v2.7.3 ich:

Creating object, there are now 1 
Creating object, there are now 2 
Exception AttributeError: "'NoneType' object has no attribute 'count'" in <bound 
method A.__del__ of <__main__.A object at 0x0234B8B0>> ignored 
Exception AttributeError: "'NoneType' object has no attribute 'count'" in <bound 
method A.__del__ of <__main__.A object at 0x0234BE90>> ignored 

ich die Auswirkungen von How do I correctly clean up a Python object? verstehen. Aber dieser Fall ist für Klassenvariablen (freigegeben oder statisch für meine C++ - Freunde). Sicherlich hat die Instanz einen Verweis auf die Klassenvariable, die nicht zuerst zerstört werden sollte, da wir noch einen Verweis darauf haben?

Ist es ein Problem oder ein Fehler, die Klasse vor Objekten dieser Klasse zu zerstören? Vielleicht ist meine Frage ‚Wo sind Klasse-Shared-Variablen gespeichert tatsächlich“

(Ja, ich verstehe, dass dies einen Kontext-Manager behoben werden kann, oder auch einfach:

del a1 
del a2 

das Objekt zu zerstören bevor die Klasse zerstört wird.)

Antwort

6

Maybe my question is 'Where are class-shared variables actually stored?"

Wenn das Ihre Frage, die Antwort „auf die Klasse“.

Ihre lar zu adressieren Frage: Wie Sie notiert haben, kann __del__ nicht auf globale Variablen verlassen --- aber A ist eine globale Variable, so dass Sie sich nicht darauf verlassen können. Interessanterweise kann ich in den Dokumenten keine offizielle Aussage dazu finden, aber es gibt im Internet verschiedene Hinweise darauf, dass __del__ keine globalen Variablen verwenden kann. Here ist ein:

When a Python program terminates the global variables in each module are set to None. The order in which this happens it undefined

Es wird funktionieren, wenn Sie die Zählung über self.__class__.count statt A.count zugreifen. (Dies ist auch der Grund, warum es funktioniert, wenn Sie self.count verwenden.)

+1

Was ist mit '.__ class__' auf der Instanz? – FatalError

+1

@FatalError: Sie haben Recht, das Referenzproblem ist ein Ablenkungsmanöver. Das Problem besteht nicht darin, dass die Klasse selbst gelöscht wurde, sondern dass die globale Variable, die darauf verweist, auf None gesetzt wurde. Ich habe meine Antwort bearbeitet. – BrenBarn

+2

Seltsamerweise bekomme ich das gleiche Verhalten, wenn ich es mit '.__ class__' versuche. Es sieht so aus, als wäre es auch auf "None" eingestellt, bevor in diesem Fall "__del__" aufgerufen wird, was irgendwie überraschend ist. – FatalError

Verwandte Themen