美文网首页
两种类级别的cache实现 2023-04-07

两种类级别的cache实现 2023-04-07

作者: 9_SooHyun | 来源:发表于2023-04-06 15:52 被阅读0次
    import functools
    import threading
    import methodtools
    
    
    class Parent:
        """
        class level cache implement
        提供两种类级别的cache实现
        第一种是与子类共享cache存储空间的实现
        第二种是类各自私有的cache存储空间的实现
        """
    
        # cached classmethod. the storage lifetime follows this `Parent` class
        # this way will share the single storage to all its subclasses
        @classmethod
        @functools.lru_cache(maxsize=1)
        def shared_cache(cls, key: str):
            print(cls.__name__, 'functools.lru_cache', key)
            return threading.Lock()
    
        # cached classmethod. the storage lifetime follows this `Parent` class
        # this way will bind the cache storages to each classes
        @methodtools.lru_cache(maxsize=1)  # note that methodtools wraps classmethod
        @classmethod
        def private_cache(cls, key: str):
            print(cls.__name__, 'methodtools.lru_cache', key)
            return threading.Lock()
    
        def instance_method(self):
            print("instance_method")
        
        @classmethod
        def class_method(cls):
            print("class_method")
        
        @staticmethod
        def static_method():
            print("static_method")
    
    
    class Child(Parent):
        pass
    
    # 番外test: subclass's classmethod is a complete copy of parent's classmethod, not a reference
    print(Parent.shared_cache is Child.shared_cache) # False
    print(Parent.private_cache is Child.private_cache) # False
    print(Parent.class_method is Child.class_method) # false
    print(Parent.instance_method is Child.instance_method) # True
    print(Parent.static_method is Child.static_method) # True
    # 这说明,当类继承发生时,子类中的classmethod是完整地从父类中全拷贝而来,而不是引用同一个method.
    # because a class method is 'bound' to the specific class
    # 而子类的 static method 和 instance method 都是直接引用父类中的method
    
    
    ins1 = Parent()
    ins2 = Child()
    
    # ----------- test shared_cache -----------
    l1 = ins1.shared_cache("1")
    l2 = ins2.shared_cache("1")
    l3 = Child.shared_cache("1")
    # 表面上看ins1和ins2都从shared_cache里面拿"1"对应的值
    # 但是被lru_cache装饰过后,最终使用的hashkey会添加上caller的类型等信息,l1和l2对应的key不同
    # ins1 和 ins2 是共享cache的,因此 l2 会把 ins1 缓存的l1 踢掉
    print(l1 is l2) # False
    print(l2 is l3) # True
    
    # ----------- test private_cache -----------
    l3 = ins1.private_cache("1")
    l4 = Parent().private_cache("1")
    
    l5 = ins2.private_cache("1")
    l6 = Child().private_cache("1")
    
    print(l3 is l4) # True
    print(l5 is l6) # True
    print(l4 is l5) # False
    

    相关文章

      网友评论

          本文标题:两种类级别的cache实现 2023-04-07

          本文链接:https://www.haomeiwen.com/subject/mesuddtx.html