代码之家  ›  专栏  ›  技术社区  ›  Eric

我怎样才能用python创建一个dead weakref?

  •  4
  • Eric  · 技术社区  · 6 年前

    有没有比以下更好的方法:

    def create_expired_weakref():
        class Tmp: pass
        ref = weakref.ref(Tmp())
        assert ref() is None
        return ref
    

    上下文:我想要我的weakref的默认状态,这样我的类可以:

    def __init__(self):
        self._ref = create_expired_weakref()
    
    def get_thing(self):
        r = self._ref()  # I need an empty weakref for this to work the first time
        if r is None:
            r = SomethingExpensive()
            self._ref = weakref.ref(r)
        return r
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   Mike Jarvis    6 年前

    另一种方法是在这里使用duck类型。如果你只关心它的行为就像一个死去的织女 self._ref() 打电话,你就可以了

    self._ref = lambda : None
    

    当我有一个相似的愿望想要一个属性,如果它可用的话,它将返回一个缓存值,但是没有其他的时候,这就是我最终使用的。我用这个lambda函数初始化了它。然后这个财产

    @property
    def ref(self):
        return self._ref()
    

    更新:感谢@Aran Fey,我看到他把这个想法作为对问题的评论,而不是回答。

        2
  •  0
  •   wizzwizz4    6 年前

    weakref.finalize 为了大好:

    import weakref
    
    def create_expired_weakref(type_=type("", (object,), {'__slots__':
                                          ('__weakref__',)})):
        obj = type_()
        ref = weakref.ref(obj)
        collected = False
    
        def on_collect():
            nonlocal collected
            collected = True
        final = weakref.finalize(obj, on_collect)
        del obj
    
        while not collected:
            pass
        return ref
    

    如果您正在调试,这可能会阻塞线程一段时间,甚至在某些模糊的情况下可能会死锁,但它保证会返回过期的weakref。