weakref
weakref 模块提供对对象的弱引用:弱引用不会增加对象的引用计数,当除弱引用外不再有强引用指向该对象时,垃圾回收器可以回收该对象并复用其内存。因此,弱引用常用于缓存(避免“仅因在缓存中”而长期保留大对象)、打破循环引用(弱引用不参与引用计数,可切断环),以及对象与附加数据的关联(对象被回收时条目自动清理)。
该模块的设计源于“引用计数 + 垃圾回收”下对生命周期控制的精细需求:普通字典/集合会强引用键或值,导致对象仅因出现在容器中就无法被回收;弱引用则允许容器“看见”对象而不“持有”对象。设计上,weakref.ref 是底层原语,适合需要手动解引用和判空的场景;weakref.proxy 则提供透明代理,访问方式像原对象,但对象被回收后访问会抛出 ReferenceError;日常开发更常用的是弱引用容器:WeakValueDictionary(值弱引用,适合键→大对象缓存)、WeakKeyDictionary(键弱引用,适合对象→附加数据)、WeakSet(元素弱引用);若只需在对象被回收时执行清理,可用 weakref.finalize 注册回调,比在 ref 上设 callback 更简单。
weakref.ref(obj[, callback])
返回 obj 的弱引用。调用返回的引用对象可得到原对象;若对象已被回收则得到 None。可选参数 callback 在对象即 将被回收时被调用(以弱引用为参数)。
import weakref
class Node:
pass
obj = Node()
r = weakref.ref(obj)
print(r() is obj) # True
del obj
print(r()) # None
tip
引用计数:CPython 用引用计数管理对象生命周期,强引用会增加计数,对象计数为 0 时被回收。弱引用不计入该计数,因此不会阻止对象被回收。