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