结论:弱引用是不增加对象引用计数的引用——通过 weakref.ref(obj) 访问目标,目标被正常回收后弱引用自动返回 None(或触发回调)。它解决"想引用一个对象但不想阻止它被回收"的问题:缓存、观察者列表、打破循环引用是三大经典场景。
展开:三种形态:1)weakref.ref——基础弱引用,调用它得到对象或 None,可注册回调在对象死亡时通知;2)weakref.proxy——透明代理,像原对象一样使用,目标死亡后访问抛 ReferenceError,适合"本来就期望对象活着"的场合;3)WeakValueDictionary/WeakSet——值(或元素)被弱引用的容器,对象死后条目自动消失,是规范化缓存(canonicalizing cache)的标准件,如字符串驻留式场景。打破循环引用:树结构子节点持父节点用 weakref.ref(parent),父持子用强引用,删除父节点整棵树自然回收。限制:内置 list、dict、str、int 等不支持弱引用(无 __weakref__ 槽),自定义类默认支持,__slots__ 类需显式加 '__weakref__'。易错点:ref(obj)() 的返回值要立即绑定再用,ref(obj)().method() 链式写法在 CPython 引用计数下可能中途对象即死(中间无强引用持有)。
import weakref
class Node: pass
n = Node()
r = weakref.ref(n)
print(r() is n) # True
del n
print(r()) # None
追问方向:finalize 与 __del__ 的对比、弱引用在 functools.lru_cache 类缓存中的应用局限。