如何在Python类中计算结果并缓存至类变量?寻求更优雅实现
解决方案
针对你的需求——将类级别的计算逻辑移出__init__、实现延迟计算(仅在类首次实例化时执行)且每个类仅计算一次,这里提供两种优雅的实现方式:
方案一:使用类级别的@property手动管理缓存
通过结合@classmethod和@property,将缓存逻辑封装为类属性,__init__只需直接引用该属性即可:
class Base: @classmethod @property def cached_result(cls): # 检查类是否已缓存结果,未缓存则执行计算 if not hasattr(cls, "_cached_result"): cls._cached_result = cls.expensive_computation() return cls._cached_result @classmethod def expensive_computation(cls): """实际场景中的耗时计算,依赖类变量""" result = 0 for item in cls.class_vars: result += item * item return result def __init__(self): # 直接引用类属性,无需在__init__中处理缓存逻辑 self.result = self.__class__.cached_result class Derived1(Base): class_vars = [1, 2, 3, 4, 5] def __init__(self): super().__init__() # 可直接使用self.result pass class Derived2(Base): class_vars = [1, 2, 3, 4, 5, 6, 7, 8] def __init__(self): super().__init__() # 可直接使用self.result pass
说明
- 首次访问
cached_result时(即第一个实例初始化时)触发计算,结果会被缓存到类的私有变量_cached_result中; - 后续实例初始化时直接复用缓存值,无需重复计算;
__init__代码被大幅简化,完全剥离了缓存判断和计算逻辑。
方案二:利用functools.lru_cache自动缓存类方法
借助标准库的lru_cache装饰器,无需手动管理缓存,代码更简洁:
from functools import lru_cache class Base: @classmethod @lru_cache(maxsize=None) # 无限制缓存类方法的结果 def expensive_computation(cls): """实际场景中的耗时计算,依赖类变量""" result = 0 for item in cls.class_vars: result += item * item return result def __init__(self): # 直接调用类方法,缓存由lru_cache自动处理 self.result = self.__class__.expensive_computation() class Derived1(Base): class_vars = [1, 2, 3, 4, 5] class Derived2(Base): class_vars = [1, 2, 3, 4, 5, 6, 7, 8]
说明
lru_cache会根据传入的cls参数(即不同的子类)分别缓存计算结果;- 第一次调用
expensive_computation时执行计算,后续调用直接返回缓存值; - 代码量最少,逻辑最清晰,无需手动编写缓存判断逻辑,维护成本极低。
方案选择
如果不想引入额外依赖(虽然functools是Python标准库),可以选择方案一;若追求代码简洁性和可读性,方案二更优,是推荐的实现方式。
内容的提问来源于stack exchange,提问作者Struggling Near Seattle
相关产品推荐
相关产品推荐

