Achtzig hat geschrieben:Andersrum gesehen könnte die Basisklasse aber dennoch solange bereitgehalten werden, bis eine abgeleitete Klasse aufgelöst ist.
Da abgeleitete Klassen eine Referenz auf ihre Basisklasse besitzen, ist das selbstverständlich der Fall. Darum funktioniert `b.__class__.__base__` auch immer. Dein Problem war nicht, dass die Basisklasse weg war, sondern das Modul war schon beseitigt.
Wenn ein Objekt nicht mehr referenziert wird und der beanspruchte Speicherbereich irgendwann durch garbage collection tatsächlich freigegeben wird, ist es mir egal, zu welchen Zeitpunkt das passiert. Wichtig ist, daß die ganze Destruktorenkette durchlaufen werden kann. Ein Objekt wird ja auch nicht feigegeben, solange es referenziert wird. Mir fehlt da ein bischen die dreidimensionale Auflösung, die ja einen wesendlichen Aspekt in der objektorientierten Programmierung darstellt.
Was meinst Du mit dreidimensionaler Auflösung?
Garbage collection an sich ist für mich nichts Neues, da es in den Achtzigern schon in BASIC-Dialekten verwendet wurde. Ungewöhnlich daran ist nur, daß eben auch Bezeichner aus dem Namensraum verschinden, die noch von einer Unterklasse benötigt werden. Das halte ich für ein Manko.
Der Name verschwindet nicht, er wurde nur an ein anderes Objekt (`None`) gebunden.
Das Problem ist, dass man bei Programmende irgendwie die Modulobjekte abräumen muss und, mit an Sicherheit grenzender Wahrscheinlichkeit in jedem nicht supertrivialen Programm, zyklische Abhängigkeiten bestehen. Und die muss man irgendwie durchbrechen. Bei Programmende und Modulen werden diese Zyklen deshalb mit "Gewalt" durchbrochen.
Der Destruktor von object könnte beispielsweise ein Signal setzen, daß das Objekt nun (irgendwann) aus dem Speicher entfernt werden kann. Damit wäre gewährleistet, daß alle abgeleiteten Destruktoren durchlaufen wurden.
`__del__()` wird erst aufgerufen, wenn ein Objekt nicht mehr Referenziert wird. Damit ist der Referenzzähler selber schon das gewünschte Signal. Und kann natürlich nicht aus der Methode gesetzt werden, die erst aufgerufen wird, wenn es bereits gesetzt *ist*.
Das Fazit ist jedenfalls, daß ich nun vom Hauptprogramm aus den geregelten Abbau vornehme, also alle Objekte, bei denen der Zeitpunkt der Freigabe nicht zufällig sein sollte, über eine Liste referenziere und die Referenzen in umgekehrter Reihenfolge freigebe. Das gleiche dann auch bei den Gruppenobjekten, die ihrerseits Objektreferenzen enthalten.
Dann betreibst Du wahrscheinlich genau das Mikromanagement, welches man mit Garbage Collection eigentlich vermeiden will. Statt mit Listen und deren Freigabe kannst Du an der Stelle auch explizit eine `close()`- oder `release()`-Methode aufrufen, was den Sinn und Zweck an der Stelle wesentlich deutlicher macht.
Vergiss `__del__()`! Die Methode ist nicht wirklich zu gebrauchen. Es wird von der Sprache nicht garantiert wann die Methode aufgerufen wird und es *wird* garantiert, dass sie *nie* aufgerufen wird, wenn eine zyklische Abhängigkeit zwischen Objekten mit einer `__del__()`-Methode besteht. Und wenn man das ständig im Blick haben will, könnte man sich gleich ums Speichermanagement selbst kümmern.