python弱引用

参考:

  • https://chengzhaoxi.xyz/5701cbbd.html
  • https://segmentfault.com/a/1190000005729873
  • https://docs.python.org/zh-cn/3/library/weakref.html

弱引用

对象被引用,分为强引用和弱引用,当对象被强引用时,对象的引用计数会增加,这会阻止对象被gc。

弱引用不会增加对象的引用计数,对象被销毁之前,弱引用都可以一直返回该对象。

弱引用的使用场景

实现保存大型对象的缓存或映射,但又不希望大对象仅仅因为它出现在高速缓存或映射中而保持存活。

例如大型的图像对象,如果用普通的字典,图像名称作为key,图像对象作为value,那么图像对象的引用将一直大于1,永远不会被清除,但我们仅仅是作为缓存使用,可以使用weakref.WeakKeyDictionary存储,这样,当对象的引用归零时,垃圾回收之后,字典中的条目也会删除。

弱引用的使用

weakref.ref(object[, callback]), 其中callback回调函数是可选参数,它在引用的对象被删除的时候被调用

class Man:
def __init__(self, name):
self.name = name

def callback(reference):
print('calling callback: ({!r})'.format(reference))

o = Man("test")
print(sys.getrefcount(o))

r = weakref.ref(o, callback)
print(r)
print(sys.getrefcount(o))
print(r())
o2 = r()
print(o2==o)
print(sys.getrefcount(o))
del o, o2
print(gc.collect())
print(r())

输出:

2
<weakref at 0x000002A835D93C28; to 'Man' at 0x000002A835E9C240>
2
<__main__.Man object at 0x000002A835E9C240>
True
3
calling callback: (<weakref at 0x000002A835D93C28; dead>)
6
None