弱引用
正是由于有引用,对象才会在内存中存在。
当对象的引用数量归零后,垃圾回收程序会把对象销毁。
可是,有时须要引用对象,而不让对象存在的时间超过所需时间。
这常常用在缓存中。
弱引用不会增长对象的引用数量。
引用的目标对象称为所指对象(referent)。
所以咱们说,弱引用不会妨碍所指对象被看成垃圾回收。
弱引用在缓存应用中颇有用,由于咱们不想仅由于被缓存引用着而始终保存缓存对象。
若是对象存在,调用弱引用能够获取对象;不然返回 None。
弱引用是可调用的对象,返回的是被引用的对象;若是所指对象不存在了,返回 None。
WeakValueDictionary简介
WeakValueDictionary 类实现的是一种可变映射,里面的值是对象的弱引用。
被引用的对象在程序中的其余地方被看成垃圾回收后,对应的键会自动从 WeakValueDictionary 中删除。
所以,WeakValueDictionary 常常用于缓存。
临时变量引用了对象,这可能会致使该变量的存在时间比预期长。
一般,这对局部变量来讲不是问题,由于它们在函数返回时会被销毁。
可是全局变量,除非显式删除,不然不会消失。
weakref 模块还提供了 WeakSet 类,按照文档的说明,这个类的做用很简单:“保存元素弱引用的集合类。元素没有强引用时,集合会把它删除。
”若是一个类须要知道全部实例,一种好的方案是建立一个WeakSet 类型的类属性,保存实例的引用。
若是使用常规的 set,实例永远不会被垃圾回收,由于类中有实例的强引用,而类存在的时间与Python 进程同样长,除非显式删除类。
弱引用的局限
不是每一个 Python 对象均可以做为弱引用的目标(或称所指对象)。
基本的 list 和 dict 实例不能做为所指对象,可是它们的子类能够轻松地解决这个问题:
class MyList(list):
"""list的子类,实例能够做为弱引用的目标"""
a_list = MyList(range(10))
# a_list能够做为弱引用的目标
wref_to_a_list = weakref.ref(a_list)
set 实例能够做为所指对象。用户定义的类型也没问题。
可是,int 和 tuple 实例不能做为弱引用的目标,甚至它们的子类也不行。