Ich ändere eine Legacy-Bibliothek, die das Singleton-Muster durch den Metaklassen-Ansatz verwendet.
Die Singleton-Klasse, die von type
erbt, definiert de __call__
function.
Im Moment wird mein Singleton-Objekt, das diese Bibliothek verwendet, niemals gelöscht. Ich habe die Methode __del__
in den Singleton-Klassen definiert und diese Funktion wird nie aufgerufen.
Klarstellung: Ich habe eine (Meta-) Klasse namens Singleton
implementiert, die von mehreren Klassen verwendet wird, wobei Singleton
als __metaclass__
verwendet wird.
Ich habe zum Beispiel class A(object)
, das __metaclass__ = Singleton
hat. Die A-Klasse hat mehrere Mitglieder, die ich zerstören möchte, wenn mein Programm endet und das A-Objekt (das einzige, das existieren kann) zerstört ist.
Ich habe versucht, __del__
method in A
class zu definieren, aber es funktioniert nicht.
__del__()
darf nicht am Prozess exit Das erste, was ich sagen soll, ist
Es ist nicht garantiert, dass
__del__()
-Methoden für Objekte aufgerufen werden, die noch existieren, wenn der Interpreter beendet wird.
Von den Python-Datenmodelldokumenten . Daher solltest du dich nicht darauf verlassen, dass du den Zustand aufräumst, den du beim Beenden aufräumen musst, und auf der höchsten Ebene, weshalb dein __del__()
möglicherweise nicht aufgerufen wird. Dafür steht atexit
.
Als Nächstes möchte ich sagen, dass CPython die Referenzzählung verwendet, um zu erkennen, dass ein Objekt freigegeben werden kann, ohne den Garbage Collector verwenden zu müssen (was zu besser vorhersagbaren CPU-Auswirkungen und potenziell effizienteren Anwendungen führt) eine Zirkelreferenz, eine ungereinigte Ausnahme, eine vergessene Schließung oder eine andere Python-Implementierung zum Brechen, und Sie sollten sich wirklich wirklich fragen, ob Sie sich darauf verlassen wollen, dass __del__()
an einem bestimmten Punkt aufgerufen wird .
Nach dem Klang würde ich vermuten, dass Ihre Singleton-Metaklasse (selbst ein Singleton ...) Ihre Singleton-Instanz beim ersten Aufruf von __call__()
beibehält. Da die Metaklasse nicht freigegeben wird, da sie zu dem Modul gehört, das selbst von sys.modules
beibehalten wird, wird diese Referenz nicht bis zum Ende des Programms verschwinden, so dass auch bei einer garantierten sofortigen Aufräumung aller externen Referenzen darauf verzichtet wird Wenn der Singleton freigegeben wird, wird Ihr __del__()
nicht aufgerufen.
atexit
-Handler hinzu, wenn Sie Ihre Singleton-Instanz erstellen, um beim Prozess-Exit die notwendigen Aufräumarbeiten auszuführen. __del__()
-Methode auf, wenn du willst. ZB können Sie sich für die Ordentlichkeit / zukünftige Erweiterbarkeit (z. B. Pluralisieren des Singletons) entscheiden, dass die Singleton-Instanz nach sich selbst aufgeräumt werden soll, wenn sie nicht mehr verwendet wird.
__del__()
-Methode implementieren, die erwartet, dass während der normalen Programmausführung aufgeräumt werden soll, werden Sie wahrscheinlich auch den atexit
-Handler entfernen wollen. weakref
, damit Sie es nicht selbst behalten. Tags und Links python singleton metaclass destructor