$search
00001 # Grabbed this handy code from here: 00002 # http://efreedom.com/Question/1-1673483/Store-Callback-Methods 00003 00004 import weakref 00005 00006 class WeakCallback (object): 00007 """A Weak Callback object that will keep a reference to 00008 the connecting object with weakref semantics. 00009 00010 This allows object A to pass a callback method to object S, 00011 without object S keeping A alive. 00012 """ 00013 def __init__(self, mcallback): 00014 """Create a new Weak Callback calling the method @mcallback""" 00015 obj = mcallback.im_self 00016 attr = mcallback.im_func.__name__ 00017 self.wref = weakref.ref(obj, self.object_deleted) 00018 self.callback_attr = attr 00019 self.token = None 00020 00021 def __call__(self, *args, **kwargs): 00022 obj = self.wref() 00023 if obj: 00024 attr = getattr(obj, self.callback_attr) 00025 attr(*args, **kwargs) 00026 else: 00027 self.default_callback(*args, **kwargs) 00028 00029 def default_callback(self, *args, **kwargs): 00030 """Called instead of callback when expired""" 00031 pass 00032 00033 def object_deleted(self, wref): 00034 """Called when callback expires""" 00035 pass 00036 00037 class WeakCallbackCb(WeakCallback): 00038 def __init__(self, mcallback): 00039 WeakCallback.__init__(self, mcallback) 00040 self._deleted_cb = None 00041 00042 def object_deleted(self, wref): 00043 if self._deleted_cb: 00044 self._deleted_cb(*self._args, **self._kwargs) 00045 # Typically, the _deleted_cb will have a reference to the 00046 # object that has us as a callback, so we need to break that 00047 # cycle after calling the callback. 00048 self.set_deleted_cb() 00049 00050 def set_deleted_cb(self, cb = None, *args, **kwargs): 00051 self._deleted_cb = cb 00052 self._args = args 00053 self._kwargs = kwargs 00054 if not cb: 00055 self._args = None 00056 self._kwargs = None 00057 00058