problem with weakref.proxy
Peter Otten
__peter__ at web.de
Sat Jan 31 12:33:24 EST 2004
Walter Haslbeck wrote:
> Hello,
>
> I'm a completly Python newbie. As a first learning project I want to port
> an game-engine I have writte some time ago in pure C to Python using OO
> methods.
>
> So I created a base-class 'GOb' (GameObject). This class should have
> a sorted list of all instances stored as as class-attribte __olist[].
>
> When I add a reference of the new created object in the constructor
> (with GOb.__olist.append(self)) I have 2 references to each created
> instance and if I 'del' the instance the destructor is not called,
> because __olist[] holds another reference to that object.
>
> Now I got to tip to use the weakref module. Well I thought this should
> be exactly what I need and changed the program to add not a reference
> to the instances but a weakref.proxy.
>
> So now my instances are deleted really deleted when I use 'del', but:
> How do get corresponding weakref.proxy object out of __olist[]?
>
> I tried to use the callback parameter from weakref.proxy, but at the
> time when the callback takes place, the proxy object is allready 'dead',
> I get an Exception when I try to remove the proxy-instance from __olist[]:
>
> Exception exceptions.ReferenceError: 'weakly-referenced object no
> longer exists' in <function proxy_callback at 0x4040c02c> ignored
>
> And if I iterate throu all objects in __olist[] I get an
> 'ReferenceError: weakly-referenced object no longer exists'
>
>
> please look at the following source:
[...]
I'd recommend being lazy and using a WeakValueDictionary instead of building
the machinery on your own. Your code would then look similar to the
following:
import weakref
class GOb:
all = weakref.WeakValueDictionary()
def c_show_all():
print "all GObs, sorted by priority:"
values = GOb.all.values()
values.sort()
for i in values:
print i
c_show_all = staticmethod(c_show_all)
def __init__(self, name="GOB", priority=0):
self.priority = priority
self.name = name
GOb.all[id(self)] = self
def __del__(self):
print "Destruktor called for GOB " + self.name
def __str__(self):
return self.name + " " + str(self.priority)
def __cmp__(self, other):
return cmp(self.priority, other.priority)
if __name__ == '__main__':
a=GOb("T1", 0)
b=GOb("T2", 2)
c=GOb("T3", 1)
GOb.c_show_all()
print "delete T1:"
del a
GOb.c_show_all()
Peter
More information about the Python-list
mailing list