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
网友评论