Reihenfolge von __del__ Aufrufen und garbage collection

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
clemens1
User
Beiträge: 2
Registriert: Mittwoch 26. August 2015, 07:50

Hallo,
ich habe das folgende Problem:

Es gibt zwei Klassen A und B. B haelt eine Referenz auf A. In einem normalen garbage collection Zyklus kann also A nicht zerstoert werden bevor B nicht zerstoert wurde. In Klasse B halte ich eine Datei offen, die erst in der __del__ Methode geschlossen wird. Klasse A soll dann in seiner __del__ Methode den Ordner loeschen in dem die Datei von B liegt. B.__del__ muss also vor A.__del__ aufgerufen werden. Mein Problem tritt nun auf, wenn der Python Interpreter normal terminiert. Dann scheint er sich um reference counts nicht mehr zu kuemmern und ruft die beiden __del__ Methoden in der "falschen" Reihenfolge auf.

Wie kann ich dieses Problem loesen? Ich habe alle moeglichen Dinge ueber reference count und garbage collection in Python gelesen, aber nichts hat mich wirklich weitergebracht. Ich habe auch gelesen, dass niemand garantiert, dass __del__ jemals aufgerufen wird. Welche Alternativen hat man dann um clean-ups zu machen.

Danke
BlackJack

@clemens1: Vergiss `__del__()`, das macht mehr Probleme als es löst, und biete eine `close()`-Methode an die der Benutzer aufrufen muss und benutze dann ``with`` und `contextlib.closing()` oder mach aus dem Objekt mit der `close()`-Methode direkt einen Kontextmanager mit `__enter__()` und `__exit__()` für die ``with``-Anweisung.
clemens1
User
Beiträge: 2
Registriert: Mittwoch 26. August 2015, 07:50

Danke fuer die schnelle Antwort. Da es sich in meinem Fall um clean up von temporary files handelt mit denen der Benutzer nichts zu tun haben sollte finde ich die Loesung nicht optimal. Da es sich hier um ein API handelt, weiss ich auch gar nicht genau wie ich das umsetzen wuerde. Instanzen von B werden mehr oder weniger automatisch angelegt und der User greift dann optional darauf zu. Ausserdem gibt es noch mehr Klassen die aehnliche Beziehungen haben. Es muss doch in Python ein Konzept oder Pattern geben, mit dem sich das in einer sauberen Art und Weise loesen laesst.

Gruss
BlackJack

@clemens1: Entweder explizit mit einer Aufräum-Methode oder mit ``with``. Anders geht das in Python nicht. Wenn nicht auf den `B`-Exemplaren, dann vielleicht auf dem/einem Objekt das Exemplare von `B` verwaltet‽ „Explicit is better than implicit.“
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:


GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

BlackJack hat geschrieben:@clemens1: Entweder explizit mit einer Aufräum-Methode oder mit ``with``. Anders geht das in Python nicht. Wenn nicht auf den `B`-Exemplaren, dann vielleicht auf dem/einem Objekt das Exemplare von `B` verwaltet‽ „Explicit is better than implicit.“
Oder "implizit" (und sicher) mit object finalizers: https://docs.python.org/3/library/weakr ... er-objects
BlackJack

@apollo13: Aber erst in Python 3.4. Habe auf die Schnelle keinen Backport gefunden. Müsste man sich also selber basteln wenn man kein 3.4 haben will oder kann.
Antworten