• Python weakref.WeakKeyDictionary与weakref.WeakValueDictionary区别和实战应用


    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

    四、小结:

    上面的示例,其实就是实现对象的存储和调用,在实例项目中的使用,只有实战,才知道弱引用实际的应用
  • 相关阅读:
    js插件zClip实现复制到剪贴板功能
    基于jQuery的滚动条插件-jquery.jscrollbar
    jquery mobile 开启开关
    html5 中audio 在safari上不支持自动播放
    开发人员常用的10个Sublime Text插件
    通过padding-bottom或者padding-top实现等比缩放响应式图片
    get请求下载json文件正常,但是不弹出status
    JSON错误
    对象与类
    数组(二)
  • 原文地址:https://www.cnblogs.com/ygbh/p/14035781.html
Copyright © 2020-2023  润新知