weakref模块主要的作用:就是一种弱类型的应用,使用此类型,内存管理不再以传统计数器的次数来实现内存的回收,
而是通过单独开辟的内存来存储实例的对象,然后通过指针地址引用的方式,实现对象的调用,
使用完成后,GC马上回收内存,从而达到高效回收内存,提高效率。
一、常用的方法有两种
weakref.WeakKeyDictionary : 实例化对象存在key里面,value可以自定义值
weakref.WeakValueDictionary : 实例化对象存在value里面,key可以自定义值
二、使用的示例
import weakref class Config(object): def say(self): print('hello') if __name__ == '__main__': ret_key = weakref.WeakKeyDictionary() ret_value = weakref.WeakValueDictionary() config_obj = Config() # 两者的区别 ret_key[config_obj] = config_obj ret_value[config_obj] = config_obj print('WeakKeyDictionary:', ret_key.__dict__.get('data')) print('WeakValueDictionary:', ret_value.__dict__.get('data')) """ 打印结果: WeakKeyDictionary: {<weakref at 0x000001FD94E8C548; to 'Config' at 0x000001FD94756780>: <__main__.Config object at 0x000001FD94756780>} WeakValueDictionary: {<__main__.Config object at 0x000001FD94756780>: <weakref at 0x000001FD94E304C0; to 'Config' at 0x000001FD94756780>} """ # 两者调用方法,都是一致的 ret_key.get(config_obj).say() ret_value.get(config_obj).say() """ 打印结果: hello hello """ # 自定义键或值 ret_key[config_obj] = 'test' ret_value['test'] = config_obj print(ret_key.get(config_obj)) print(ret_value.get('test')) """ 打印结果: test <__main__.Config object at 0x000001D224986828> """
三、实际应用
注意:此代码来源Tornado源码
httpclient.py @classmethod def _async_clients(cls) -> Dict[IOLoop, "AsyncHTTPClient"]: attr_name = "_async_client_dict_" + cls.__name__ if not hasattr(cls, attr_name): setattr(cls, attr_name, weakref.WeakKeyDictionary()) #给实例化类属性增加一个WeakKeyDictionary的类型,然后把loop实例设置为key和value return getattr(cls, attr_name) def __new__(cls, force_instance: bool = False, **kwargs: Any) -> "AsyncHTTPClient": io_loop = IOLoop.current() if force_instance: instance_cache = None else: instance_cache = cls._async_clients() if instance_cache is not None and io_loop in instance_cache: return instance_cache[io_loop] # 在WeakKeyDictionary获取值 instance = super(AsyncHTTPClient, cls).__new__(cls, **kwargs) # type: ignore instance._instance_cache = instance_cache if instance_cache is not None: instance_cache[instance.io_loop] = instance # 给WeakKeyDictionary类型设置值 return instance
四、小结:
上面的示例,其实就是实现对象的存储和调用,在实例项目中的使用,只有实战,才知道弱引用实际的应用