weakrefs and bound methods

Marc 'BlackJack' Rintsch bj_666 at gmx.net
Sun Oct 7 12:26:31 EDT 2007


On Sun, 07 Oct 2007 16:51:33 +0200, Mathias Panzenboeck wrote:

> import weakref
> 
> class Wrapper(object):
> 	def __init__(self,x):
> 		self.x = weakref.ref(x)
> 
> 	def __call__(self,*args,**kwargs):
> 		x = self.x()
> 		if x is None:
> 			print "lost reference"
> 		else:
> 			return x(*args,**kwargs)
> 
> class Foo(object):
> 	def __init__(self):
> 		self._methods = set()
> 		self._methods.add(Wrapper(self._foo))
> 
> 	def _foo(self):
> 		print "_foo"
> 
> 	def callMethods(self):
> 		for method in self._methods:
> 			method()
> 
> 	def __del__(self):
> 		print "del Foo"
> 
> class Bar(object):
> 	def __init__(self):
> 		self._methods = set()
> 		self._methods.add(self._foo)
> 
> 	def _foo(self):
> 		print "_foo"
> 
> 	def callMethods(self):
> 		for method in self._methods:
> 			method()
> 
> 	def __del__(self):
> 		print "del Bar"
> 
> 
> 
> Now look what happens when I do this:
> 
>>>> f=Foo()
>>>> f.callMethods()
> lost reference
>>>> del f
> del Foo
>>>> b=Bar()
>>>> b.callMethods()
> _foo
>>>> del b
>>>>
> 
> Foo looses the reference to its method but Bar on the other hand has a refloop and
> never gets deleted.

``del b`` just deletes the name `b`.  It does not delete the object. 
There's still the name `_` bound to it in the interactive interpreter. 
`_` stays bound to the last non-`None` result in the interpreter.

Drop all those `__del__()` methods as they prevent the garbage collector
from collecting "cycles".

Ciao,
	Marc 'BlackJack' Rintsch



More information about the Python-list mailing list