您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

使用python WeakSet启用回调功能

使用python WeakSet启用回调功能

您不能创建对方法对象的弱引用方法对象是 短暂的 ; 它们是在您访问实例上的名称时动态创建的。请参阅描述符howto的工作原理。

当您访问方法名称时,将为您创建一个 新的 方法对象,然后将该方法添加到中WeakSet,不再有对其的其他引用,因此垃圾回收很高兴再次对其进行清理。

您将不得不存储一些不太瞬变的东西。存储实例对象本身可以工作,然后在已注册的回调中调用预定义方法

def __del__(self):
    for f in self.destroyCallback:
        f.destroyedObjectListener(self)

注册

a1.destroyCallback.add(b)

您还可以通过给它一个方法使b 自己 成为可调用__call__

class ClassB:
    def __call__(self,obj):
        print('ClassB object %d is called because obj %d '
              'is being destroyed' % (id(self), id(obj)))

另一种方法是存储对基础函数对象的引用以及对实例的引用:

import weakref


class ClassA:
    def __init__(self):
        self._callbacks = []

    def registerCallback(self, callback):
        try:
            # methods
            callback_ref = weakref.ref(callback.__func__), weakref.ref(callback.__self__)
        except AttributeError:
            callback_ref = weakref.ref(callback), None
        self._callbacks.append(callback_ref)

    def __del__(self):
        for callback_ref in self._callbacks:
            callback, arg = callback_ref[0](), callback_ref[1]
            if arg is not None:
                # method
                arg = arg()
                if arg is None:
                    # instance is gone
                    continue
                callback(arg, self)
                continue
            else:
                if callback is None:
                    # callback has been deleted already
                    continue
                callback(self)

演示:

>>> class ClassB:
...     def listener(self, deleted):
...         print('ClassA {} was deleted, notified ClassB {}'.format(id(deleted), id(self)))
... 
>>> def listener1(deleted):
...     print('ClassA {} was deleted, notified listener1'.format(id(deleted)))
... 
>>> def listener2(deleted):
...     print('ClassA {} was deleted, notified listener2'.format(id(deleted)))
... 
>>> # setup, one ClassA and 4 listeners (2 methods, 2 functions)
... 
>>> a = ClassA()
>>> b1 = ClassB()
>>> b2 = ClassB()
>>> a.registerCallback(b1.listener)
>>> a.registerCallback(b2.listener)
>>> a.registerCallback(listener1)
>>> a.registerCallback(listener2)
>>> 
>>> # deletion, we delete one instance of ClassB, and one function
... 
>>> del b1
>>> del listener1
>>> 
>>> # Deleting the ClassA instance will only notify the listeners still remaining
... 
>>> del a
ClassA 4435440336 was deleted, notified ClassB 4435541648
ClassA 4435440336 was deleted, notified listener2
python 2022/1/1 18:51:16 有352人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶