如何在python中创建一个死weakref?

如何在python中创建一个死weakref?,python,weak-references,Python,Weak References,有没有比以下更好的方法: 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):

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

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

使用
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。

另一种方法是在此处使用duck键入。如果您所关心的只是它对于
self.\u ref()
调用的行为就像一个死结,那么您可以这样做

self._ref = lambda : None
当我有一个类似的愿望,想要拥有一个属性,如果该属性可用,它将返回一个缓存的值,但除此之外没有其他属性时,我最终使用了这个属性。我用这个lambda函数初始化了它。然后,财产被没收了

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

更新:归功于@Aran Fey,我看到他将此想法作为对问题的评论,而不是回答。

它必须是
weakref.ref
对象吗?如果你不关心类型,你可以使用
lambda:None
作为默认值。@Aran Fey:好主意-这对我的用例很有效,但我仍然好奇是否有办法产生真正的weakref(例如,这会让mypy感到高兴),或者如果你不喜欢lambda:,可以使用
type(None)