problem with weakref.proxy

Peter Otten __peter__ at web.de
Sat Jan 31 18:58:36 CET 2004


Peter Otten wrote:

> I'd recommend being lazy and using a WeakValueDictionary instead of
> building the machinery on your own. Your code would then look similar to

If you want to keep your original design, just use ref instead of proxy:

import weakref

class GOb:

    __olist=[]

    def c_show_all():
        print "all GObs, sorted by priority:"
        for i in GOb.__olist:
            i().show()

    def proxy_callback(x):
        print "weakref.proxy 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.ref(self, GOb.proxy_callback)
        GOb.__olist.append(ref)
        GOb.__olist.sort(lambda x, y: cmp(x(), y()))

    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()
    print "delete T1:"
    del a
    GOb.c_show_all()

The line that failed in your original version is

GOb.__olist.remove(x)

because x is found in __olist by comparing against the list items - and the
proxy automatically delegates this to the no longer existing object. With
ref you have to explicitly dereference by calling (as seen in
__olist.sort() in the __init__() method).
As that step is not performed by the list.remove() method, only ref instead
of GOb instances are compared and the callback succeeds.

Peter 






More information about the Python-list mailing list