weakrefs and bound methods

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Fri Oct 5 12:47:35 EDT 2007


Mathias Panzenboeck a écrit :

About the lost weakref problem: in Python, methods are just tiny 
wrappers around the object, class and function created at lookup time 
(yes, on *each* lookup) (and WWAI, they are by the function object 
itself, which implements the descriptor protocol).

> When I change the class Wrapper to following, the class Foo works:
> 
> class Wrapper(object):
> 	def __init__(self,x):
> 		self.func_name = x.func_name
> 		self.x         = weakref.ref(x.im_self)

> 	def __call__(self,*args,**kwargs):
> 		x = self.x()
> 		if x is None:
> 			print "lost reference"
> 		else:
> 			return getattr(x,self.func_name)(*args,**kwargs)

Anyway, the whole thing looks quite baroque to me - and I'm known for my 
immoderate appetite for brain-melting features....

If I understand correctly, you're doing all this to avoid circular 
references while keeping track of a list of methods to call ?

If yes, then you're thru much pain for nothing. Mostly because there are 
  other much more simpler solutions. The first one is obviously to use 
names and getattr. In it's most naïve implementation, this would look like:

class Foo(object):
     def __init__(self):
	self._methods = set()
	self._methods.add('_foo')

     def _foo(self):
	print "_foo"

     def callMethods(self):
	 for name in self._methods:
              meth = getattr(self, name, None)
              if callable(meth):
                  meth()




Now if _methods is supposed to have the same content class-wise (which 
is the case in your exemple), no need to have it as an instance method:

class Foo(object):
     _methods = set('_foo')

     def _foo(self):
	print "_foo"

     def callMethods(self):
	 for name in self._methods:
              meth = getattr(self, name, None)
              if callable(meth):
                  meth()

We could go further, like using a decorator to mark methods to add to 
_methods, and a metaclass to set the whole thing up, but this would 
probably be overkill. Unless there are other requirements, I'd 
personnaly stop here.

Oh, and yes, while we're at it : Python usually knows how to deal with 
circular references....

> But that's ugly. 

Indeed.

> Any better idea?

Yes. KISS.



More information about the Python-list mailing list