2017-01-29 2 views
2

Ich schreibe eine Klasse, die von einer Bibliothek erbt.Destruktoren überschreiben, ohne ihre Eltern anzurufen

In dieser Klasse überschreibe ich den Destruktor, so dass ich eine Funktion aufrufen kann, die auf eine bestimmte Weise putzt. Wenn ich nicht aufrufen super() .__ del __() bedeutet das immer noch, dass Ressourcen bei der Zerstörung der Klasse gereinigt werden? Gibt es eine Chance, dass dieser Code zum Beispiel ein Speicherleck einführt?

class foo(some_library): 
    ... 

    def __del__(self): 
     self.proprietary_cleaning_function() 

sind Funktionen wie __init__ oder __del__ anders in der Art, wie sie außer Kraft gesetzt werden und macht den Garbage Collection-Mechanismus in Python Arbeit nach __del__?

Antwort

2

Nein, Sie müssen den Basisklassen-Destruktor explizit aufrufen, um sicherzustellen, dass Python das Objekt vollständig löscht.

Von documentation:

Wenn eine Basisklasse eine __del__() Methode hat, die __del__() der abgeleiteten Klasse Verfahren, falls vorhanden, muss sie explizit aufrufen ordnungsgemäße Löschung die Basisklasse Teil der Instanz zu gewährleisten.

Beachten Sie auch, dass seit __del__() Methode nur bei Zähler Ihre Objektreferenz genannt wird Null erreicht, gibt es einige gemeinsame Situationen, die aus gehen auf Null umfassen den Referenzzähler eines Objekts verhindern kann:

Kreis Verweise zwischen Objekten (z. B. eine doppelt verknüpfte Liste oder eine Baumstruktur mit Eltern- und Kindzeigern); eine Referenz auf das Objekt auf dem Stapelrahmen einer Funktion, die eine Ausnahme gefangen hat (die Traceback in sys.exc_info() gespeicherten speichert das Stack-Frame am Leben); oder eine Referenz auf das Objekt auf dem Stapelrahmen, das eine unbehandelte Ausnahme im interaktiven Modus ausgelöst hat (die in sys.last_traceback gespeicherte Rückverfolgung hält den Stapelrahmen am Leben).

Die erste Situation kann nur behoben werden, indem die Zyklen explizit unterbrochen werden; Die zweite kann aufgelöst werden, indem der Verweis auf das Traceback-Objekt freigegeben wird, wenn es nicht mehr nützlich ist, und der dritte kann aufgelöst werden, indem None in sys.last_traceback gespeichert wird. Circular-Referenzen , die Müll sind, werden erkannt und bereinigt, wenn der Kollektor des zyklischen Mülls aktiviert ist (standardmäßig aktiviert). Weitere Informationen zu diesem Thema finden Sie in der Dokumentation für das GC-Modul.

+0

Ist das der gleiche Fall für, wenn die \ _ \ _ del \ _ \ _ Methode nicht in der Elternklasse implementiert ist? d. h. übergeordnete Objekte del? – GLaDOS

+0

@GLaDOS Nein, wenn die Elternklasse nicht die Methode '__del__' hat. Aber wenn die Methode eingebaut ist, müssen Sie sie noch explizit aufrufen. – Kasramvd