Python 3.8中使用lru_cache实现类继承触发TypeError问题求助
问题原因分析
lru_cache装饰器是用来缓存函数或方法的调用结果的,不能直接装饰类。当你用它装饰类时,Python会把类当作可调用对象(类本身就是创建实例的可调用体)处理,但lru_cache的内部逻辑在处理类这种特殊对象时,会因为类的构造逻辑和普通函数差异,在Python 3.8版本中触发cache_info_type缺失的错误——本质就是用错了装饰器的适用场景。
修复方案
要实现类实例的缓存(比如单例、固定数量的复用实例),应该把lru_cache装饰在类的__new__方法上,因为__new__是Python负责创建类实例的核心方法。
修正后的代码示例
from functools import lru_cache class A: @lru_cache(maxsize=1) def __new__(cls): # 调用父类的__new__创建实例 return super().__new__(cls) def __init__(self): pass class B(A): @lru_cache(maxsize=1) def __new__(cls): return super().__new__(cls) # 测试效果 b1 = B() b2 = B() print(b1 is b2) # 输出True,说明是同一个实例
补充说明
- 如果希望子类B直接复用父类A的缓存逻辑,可以不用在B中重新装饰
__new__,但这样A和B的实例缓存会共用同一个lru_cache(不符合每个类单独缓存的需求),所以建议每个需要单独缓存实例的类都单独装饰自己的__new__方法。 maxsize=1表示只缓存1个实例,完全匹配你“每个类仅创建一个可复用实例”的需求。
内容的提问来源于stack exchange,提问作者Shawn
相关产品推荐
相关产品推荐

