Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Question about weakref

Reply
Thread Tools

Question about weakref

 
 
Frank Millman
Guest
Posts: n/a
 
      07-04-2012
Hi all

I have a situation where I thought using weakrefs would save me a bit of
effort.

I have a basic publish/subscribe scenario. The publisher maintains a
list of listener objects, and has a method whereby a listener can
subscribe to the list by passing in 'self', whereupon it gets added to
the list.

When the publisher has something to say, it calls a pre-defined method
on each of the listeners. Simple, but it works.

The listeners are fairly transient, so when they go out of scope, I need
to remove them from the list maintained by the publisher. Instead of
keeping track of all of them and removing them explicitly, I thought of
using weakrefs and let them be removed automatically.

It almost works. Here is an example -

import weakref

class A: # the publisher class
def __init__(self):
self.array = []
def add_b(self, b):
self.array.append(weakref.ref(b, self.del_b))
def del_b(self, b):
self.array.remove(b)
def chk_b(self, ref):
for b in self.array:
b().hallo(ref)

class B: # the listener class
def __init__(self, a, name):
self.name = name
a.add_b(self)
def hallo(self, ref):
print(self.name, 'hallo from', ref)
def __del__(self):
print('%s deleted' % self.name)

a = A()
x = B(a, 'test x')
y = B(a, 'test y')
z = B(a, 'test z')
a.chk_b(1)
del x
a.chk_b(2)
del y
a.chk_b(3)
del z
a.chk_b(4)
print(a.array)

The output is as expected -

test x hallo from 1
test y hallo from 1
test z hallo from 1
test x deleted
test y hallo from 2
test z hallo from 2
test y deleted
test z hallo from 3
test z deleted
[]

Then I tried weakref.proxy.

I changed
self.array.append(weakref.ref(b, self.del_b))
to
self.array.append(weakref.proxy(b, self.del_b))
and
b().hallo(ref)
to
b.hallo(ref)

I got the same result.

Then I varied the order of deletion - instead of x, then y, then z, I
tried x, then z, then y.

Now I get the following traceback -

test x hallo from 1
test y hallo from 1
test z hallo from 1
test x deleted
test y hallo from 2
test z hallo from 2
Exception ReferenceError: 'weakly-referenced object no longer exists' in
<bound
method A.del_b of <__main__.A object at 0x00A8A750>> ignored
test z deleted
test y hallo from 3
Traceback (most recent call last):
File "F:\junk\weaklist.py", line 70, in <module>
a.chk_b(3)
File "F:\junk\weaklist.py", line 51, in chk_b
b.hallo(ref)
ReferenceError: weakly-referenced object no longer exists
test y deleted

If I go back to using weakref.ref, but with the new deletion order, it
works.

So now I am confused.

1. Why do I get the traceback?

2. Can I rely on using weakref.ref, or does that also have some problem
that has just not appeared yet?

Any advice will be appreciated.

BTW, I am using python 3.2.2.

Thanks

Frank Millman

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Question about weakref Ian Kelly Python 0 07-06-2012 05:48 PM
Re: Question about weakref Frank Millman Python 0 07-06-2012 07:00 AM
Re: Question about weakref Dieter Maurer Python 0 07-05-2012 05:47 PM
Re: Question about weakref Frank Millman Python 0 07-05-2012 11:21 AM
Re: Question about weakref Dieter Maurer Python 0 07-05-2012 08:46 AM



Advertisments