__del__
ist ein Finalizer . Es wird aufgerufen, wenn ein Objekt durch Müll gesammelt wird. Dies geschieht irgendwann, nachdem alle Verweise auf das Objekt gelöscht wurden.
In einem einfachen Fall kann dies direkt nach dem Sagen del x
oder, wenn x
es sich um eine lokale Variable handelt, nach dem Ende der Funktion erfolgen. Insbesondere wird CPython (die Standard-Python-Implementierung), sofern keine Zirkelverweise vorhanden sind, sofort Speicherbereinigung durchführen.
Dies ist jedoch ein Implementierungsdetail von CPython. Die einzige erforderliche Eigenschaft der Garbage Collection Python ist , dass es passiert , nachdem alle Verweise gelöscht wurden, so könnte dies nicht notwendig passiert direkt nach und kann nicht passieren .
Darüber hinaus können Variablen aus vielen Gründen eine lange Lebensdauer haben , z. B. kann eine sich ausbreitende Ausnahme oder eine Modul-Introspektion die Anzahl der Variablenreferenzen über 0 halten. Außerdem kann die Variable Teil des Referenzzyklus sein - CPython mit aktivierter Garbage Collection unterbricht die meisten Unterbrechungen , aber nicht alle, solche Zyklen, und selbst dann nur periodisch.
Da Sie keine Garantie dafür haben, dass es ausgeführt wird, sollten Sie niemals den Code einfügen, in den Sie ausgeführt werden müssen. __del__()
Stattdessen gehört dieser Code zur finally
Klausel des try
Blocks oder zu einem Kontextmanager in einer with
Anweisung. Es gibt jedoch gültige Anwendungsfälle für __del__
: Wenn ein Objekt beispielsweise X
auf Y
eine Y
Referenzkopie in einem globalen cache
( cache['X -> Y'] = Y
) verweist und diese aufbewahrt, ist es höflich X.__del__
, auch den Cache-Eintrag zu löschen.
Wenn Sie wissen, dass der Destruktor (unter Verstoß gegen die obige Richtlinie) eine erforderliche Bereinigung bereitstellt, möchten Sie diese möglicherweise direkt aufrufen , da sie als Methode nichts Besonderes enthält : x.__del__()
. Natürlich sollten Sie dies nur tun, wenn Sie wissen, dass es nichts ausmacht, zweimal angerufen zu werden. Als letzten Ausweg können Sie diese Methode mit neu definieren
type(x).__del__ = my_safe_cleanup_method