[Python-3000] weakrefs of bound methods
Nick Craig-Wood
nick at craig-wood.com
Sun Feb 17 10:29:56 CET 2008
On Fri, Feb 15, 2008 at 01:20:03PM -0800, Guido van Rossum wrote:
> But maybe given how rare the use case is, it would be easier to just
> create a custom class in weakref.py that does what Nick requested.
I still don't like the silent failure, but a noisy failure and a
custom class would be great.
FYI here is the class I was writing which tripped me up. I created
this to untangle some spaghetti code in a reasonably complex GUI
application I'm writing.
Instead of there being lots of hardcoded callbacks in the GUI objects
I made a central registry which made the code a lot cleaner. The
weakrefs avoided registration and deregistration.
Since this is used from GUI code all the callback functions I needed
to add are bound methods.
(The last time I got tripped by this was a similar case involving 3rd
parties registering interests in other classes changing.)
------------------------------------------------------------
class Callback(object):
"""
A holder for functions which need to be called back at some specific point
Silently fails if you pass in bound methods!
"""
def __init__(self):
self.fns = WeakKeyDictionary()
def add(self, fn):
"""Add function to be called later."""
self.fns[fn] = True
def call(self):
"""Call all the registered functions"""
for fn in self.fns.keys():
fn()
------------------------------------------------------------
Here is my explicit (no introspection) work-around - there are
obviously better solutions!
class Callback(object):
"""
A holder for functions which need to be called back at some specific point
"""
def __init__(self):
self.fns = WeakKeyDictionary()
def add(self, fn, attribute=None):
"""
Add function to be called later. Either pass in a function,
or an object and an attribute to call. Don't pass in bound
methods since you can't take a weakref of a bound method. It
holds weakrefs so doesn't need to be deregistered.
"""
self.fns[fn] = attribute
def call(self):
"""Call all the registered functions"""
for fn, attribute in self.fns.iteritems():
if attribute is not None:
fn = getattr(fn, attribute)
fn()
--
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick
More information about the Python-3000
mailing list