problem with weakref.proxy

Walter Haslbeck news at badblocks.de
Sat Jan 31 14:52:45 CET 2004


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:

################################################################################

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

################################################################################

any hints?

Walter



More information about the Python-list mailing list