
Hallo, folgendes Problem: Ich habe ein Klasse, deren Objekte in einer sortierten Liste gehalten werden. Die Liste ist in der Basisklasse als Klassenattribut definiert. Wenn ich nun ein instanziertes Objekt dieser Klasse mit 'del' lösche, wird der Destruktor (darin würde ich gerne die Objektreferenz aus der Liste löschen) nicht aufgerufen, da ja in Liste noch eine Referenz auf dieses Objekt besteht. Als Workaround hab ich eine Methode 'remove' erstellt, die erst das Objekt aus der Liste entfernt. Anschliessend kann ich mit del das Objekt löschen. Das gefällt mir garnicht... Gibt es eine Möglichkeit, eine Referenz auf eine Objekt in der Liste abzulegen, ohne den Python-internen Objekt-Referenzzähler zu berühren? (Sorry, falls das eine FAQ ist, aber ich bin absoluter Python Newbie) ################################################################################ class GOb: __olist=[] def c_show_all(): for i in GOb.__olist: i.show() def __c_add__(gob): GOb.__olist.append(gob) GOb.__olist.sort() def __c_remove__(gob): GOb.__olist.remove(gob) c_show_all=staticmethod(c_show_all) __c_add_=staticmethod(__c_add__) __c_remove_=staticmethod(__c_remove__) def __init__(self, name="GOB", priority=0): self.priority=priority self.name=name GOb.__c_add__(self) # WORKAROUND? def remove(self): GOb.__c_remove__(self) # SO GEHTS NICHT # def __del__(self): # print "destruktor called fuer " + self.name # GOb.__c_remove__(self) def show(self): print self.name + " " + str(self.priority) def __cmp__(self, other): if self.priority < other.priority: return -1 elif self.priority == other.priority: return 0 else: return 1 if __name__ == '__main__': a=GOb("T1", 0) b=GOb("T2", 2) c=GOb("T3", 1) print "--- ALLE ---" GOb.c_show_all() print "--- DELETED SOME ---" a.remove() del a GOb.c_show_all() ################################################################################ Walter _______________________________________________ Python-de maillist - Python-de@python.net http://python.net/mailman/listinfo/python-de

Hi, Walter Haslbeck wrote:
Wenn ich nun ein instanziertes Objekt dieser Klasse mit 'del' lösche, wird der Destruktor (darin würde ich gerne die Objektreferenz aus der Liste löschen) nicht aufgerufen, da ja in Liste noch eine Referenz auf dieses Objekt besteht.
Hilft dir das Modul weakref? Gruß, Stefan _______________________________________________ Python-de maillist - Python-de@python.net http://python.net/mailman/listinfo/python-de

Stefan Fleiter <stefan.fleiter@web.de> wrote:
Hilft dir das Modul weakref?
Vielen Dank! (auch an alle die direkt per Mail geantwortet haben). weakref sollte genau das sein, was ich hier brauche. Walter _______________________________________________ Python-de maillist - Python-de@python.net http://python.net/mailman/listinfo/python-de

Stefan Fleiter <stefan.fleiter@web.de> wrote:
Hilft dir das Modul weakref?
OK, nun hab ich mein Problem mit weakref. Erstmal der Code: ################################################################################ import weakref class GOb: __olist=[] def c_show_all(): for i in GOb.__olist: i.show() def proxy_callback(x): print "callback" GOb.__olist.remove(x) proxy_callback=staticmethod(proxy_callback) c_show_all=staticmethod(c_show_all) def __init__(self, name="GOB", priority=0): self.priority=priority self.name=name ref=weakref.proxy(self, GOb.proxy_callback) GOb.__olist.append(ref) GOb.__olist.sort() def __del__(self): print "Destruktor called for GOB " + self.name def show(self): print self.name + " " + str(self.priority) def __cmp__(self, other): if self.priority < other.priority: return -1 elif self.priority == other.priority: return 0 else: return 1 if __name__ == '__main__': a=GOb("T1", 0) b=GOb("T2", 2) c=GOb("T3", 1) GOb.c_show_all() del a GOb.c_show_all() ################################################################################ So klappts leider nicht, denn: Wenn der callback des Proxy-Objektes aufgerufen wird, ist das Objekt schon nicht mehr existent und der Destruktor des Objektes wird noch später aufgerufen: $ python ex.py 1 0 T3 1 T2 2 callback Exception exceptions.ReferenceError: 'weakly-referenced object no longer exists' in <function proxy_callback at 0x403c5fb4> ignored Destruktor called for GOB T1 [...] Die Doku sagt: ... 'callback', if given, is called with a reference to the proxy when it is about to be finalized... Hm, 'about to' übersetze ich mich 'kurz bevor', also sollte ja zu der Zeit, in der der callback stattfindet das Objekt noch existieren, oder? Wie krieg ich das Objekt wieder aus meiner __olist[]? Walter _______________________________________________ Python-de maillist - Python-de@python.net http://python.net/mailman/listinfo/python-de
participants (2)
-
Stefan Fleiter
-
Walter Haslbeck