1234567891011121314151617181920212223242526272829303132333435363738394041 |
- from weakref import ref
- class _weak_callable:
- def __init__(self,obj,func):
- self._obj = obj
- self._meth = func
- def __call__(self,*args,**kws):
- if self._obj is not None:
- return self._meth(self._obj,*args,**kws)
- else:
- return self._meth(*args,**kws)
- def __getattr__(self,attr):
- if attr == 'im_self':
- return self._obj
- if attr == 'im_func':
- return self._meth
- raise AttributeError(attr)
- class WeakMethod:
- """ Wraps a function or, more importantly, a bound method, in
- a way that allows a bound method's object to be GC'd, while
- providing the same interface as a normal weak reference. """
- def __init__(self,fn):
- try:
- self._obj = ref(fn.im_self)
- self._meth = fn.im_func
- except AttributeError:
- # It's not a bound method.
- self._obj = None
- self._meth = fn
- def __call__(self):
- if self._dead(): return None
- return _weak_callable(self._obj(),self._meth)
- def _dead(self):
- return self._obj is not None and self._obj() is None
|