Python创建类实例时如何让指定方法自动优先于其他类方法执行?
Python类指定方法优先执行并缓存结果的最优实现方案
需求核心
需要让类的指定方法(如示例中的baz)优先于其他业务方法执行一次,计算结果存入cache变量复用,减少重复调用开销。
方案1:实例化时直接预执行(优先推荐)
这是最简洁、维护成本最低的实现方式,适合绝大多数常规场景。
适用场景
预执行方法计算量小,实例化后必然会调用类的业务方法。
代码实现
class Foo: def __init__(self, bar): self.bar = bar self.cache = [] # 实例化阶段直接执行预定义方法,一次计算全局复用 self.baz() def baz(self): # 你的计算逻辑 calc_result = self.bar * 100 self.cache.append(calc_result) return 0 def qux(self): # 直接使用缓存结果,无需判断预执行方法是否运行 return self.cache[0]
方案2:懒加载预执行(适用于高计算成本场景)
如果预执行方法计算开销极大,不想在实例化时就占用资源,只有第一次调用业务方法时才触发预执行,可以用该方案。
适用场景
预执行方法耗时高,存在实例化后长期不调用类方法的场景。
代码实现
通过重写__getattribute__魔法方法统一拦截所有公开方法调用,自动判断是否需要执行预执行方法:
class Foo: # 配置需要预执行的方法名 _pre_exec_method = "baz" def __init__(self, bar): self.bar = bar self.cache = [] # 预执行标记,避免重复调用 self._pre_exec_done = False def __getattribute__(self, name): # 先获取属性原始值 attr = super().__getattribute__(name) pre_method = super().__getattribute__("_pre_exec_method") pre_done = super().__getattribute__("_pre_exec_done") # 拦截条件:可调用的公开方法、不是预执行方法本身、未完成预执行 if callable(attr) and name != pre_method and not name.startswith("_") and not pre_done: super().__getattribute__(pre_method)() super().__setattr__("_pre_exec_done", True) return attr def baz(self): # 高成本计算逻辑 calc_result = self.bar * 100 self.cache.append(calc_result) return 0 def qux(self): return self.cache[0]
补充方案:装饰器标记需依赖预执行的方法
如果只有部分方法需要依赖预执行结果,不需要所有方法都触发预执行,可以用装饰器实现更灵活的控制:
def require_pre_exec(pre_method_name): def decorator(func): def wrapper(self, *args, **kwargs): if not getattr(self, "_pre_exec_done", False): getattr(self, pre_method_name)() setattr(self, "_pre_exec_done", True) return func(self, *args, **kwargs) return wrapper class Foo: def __init__(self, bar): self.bar = bar self.cache = [] self._pre_exec_done = False def baz(self): calc_result = self.bar * 100 self.cache.append(calc_result) self._pre_exec_done = True @require_pre_exec("baz") def qux(self): # 加了装饰器的方法会自动触发预执行 return self.cache[0] def common_method(self): # 未加装饰器的方法不会触发预执行 return self.bar
方案选型建议
- 常规场景优先选方案1,无魔法方法黑盒,调试和维护成本最低
- 预执行方法计算开销极高的场景选方案2,避免不必要的资源浪费
- 只有部分方法依赖预执行结果的场景选补充方案,灵活性更高
- 多线程并发场景下可在预执行逻辑中增加线程锁,避免并发时重复执行
内容的提问来源于stack exchange,提问作者Anish Sinha
相关产品推荐
相关产品推荐

