You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将类方法重构到抽象基类,拆分逻辑且不改变基类方法签名?

重构抽象基类子类的优化方案

问题背景

现有类current_class的func方法包含A、B两个独立逻辑:逻辑A负责加载大型字典dataset,逻辑B依赖dataset.keys()执行操作。代码如下:

class current_class:
    def func(self):
        # 执行A相关逻辑
        # 执行B相关逻辑

需要创建仅包含逻辑A的another_class:

class another_class:
    def func(self):
        # 执行A相关逻辑

核心要求:

  • 两个类均继承抽象基类base
  • 逻辑A在基类中实现,避免代码冗余
  • current_class无需重复加载dataset
  • 保证子类方法签名一致

现有方案及缺陷

方案1

from abc import ABC, abstractmethod

class base(ABC):
    @abstractmethod
    def func(self):
        pass
    def func_A(self):
        # 执行A相关逻辑并获取dataset
        return dataset.keys()

class current_class(base):
    def func_B(self, keys):
        # 执行B相关逻辑
    def func(self):
        keys = self.func_A()
        self.func_B(keys)

class another_class(base):
    def func(self):
        _ = self.func_A() # 返回值未使用

缺陷:another_class调用func_A时返回的keys未被使用,存在不必要的资源开销。

方案2

from abc import ABC, abstractmethod

class base(ABC):
    @abstractmethod
    def func(self):
        pass

class current_class(base):
    def func_A(self):
        # 执行A相关逻辑并获取dataset
        return dataset.keys()
    def func_B(self, keys):
        # 执行B相关逻辑
    def func(self):
        keys = self.func_A()
        self.func_B(keys)

class another_class(base):
    def func_A(self):
        # 执行与current_class相同的A逻辑,无返回值
    def func(self):
        self.func_A()

缺陷:func_A的逻辑在两个子类中重复实现,导致代码冗余,后期维护成本高。

优化方案:属性缓存+按需调用

利用基类的属性缓存机制处理逻辑A,子类按需触发加载并执行对应逻辑,既消除冗余又避免资源浪费:

from abc import ABC, abstractmethod

class base(ABC):
    def __init__(self):
        self._dataset = None  # 缓存加载后的大型字典
    
    def _load_dataset(self):
        # 这里编写逻辑A:加载大型字典dataset
        # 示例:self._dataset = {"user1": "data1", "user2": "data2"}
        pass
    
    @property
    def dataset(self):
        # 懒加载:仅在首次访问时执行逻辑A
        if self._dataset is None:
            self._load_dataset()
        return self._dataset
    
    @abstractmethod
    def func(self):
        pass

class current_class(base):
    def _execute_func_B(self):
        # 逻辑B直接使用缓存的dataset的keys
        keys = self.dataset.keys()
        # 编写逻辑B的具体操作
        pass
    
    def func(self):
        # 访问dataset属性自动触发逻辑A,再执行逻辑B
        self._execute_func_B()

class another_class(base):
    def func(self):
        # 仅触发逻辑A:访问dataset属性完成加载
        _ = self.dataset

方案优势

  • 无代码冗余:逻辑A(加载dataset)仅在基类中实现一次,所有子类共享
  • 性能优化:dataset采用懒加载+缓存机制,current_class多次使用也不会重复加载
  • 资源无浪费:another_class仅触发加载操作,无多余返回值开销
  • 扩展性强:后续若another_class需要逻辑B,可直接复用_execute_func_B方法或自行实现
  • 符合抽象基类要求:两个子类均实现了抽象方法func,签名完全一致

可选简化方案

如果对返回值的轻微开销可以接受,也可以采用更简洁的实现:

from abc import ABC, abstractmethod

class base(ABC):
    def func_A(self):
        # 执行逻辑A,加载并返回dataset
        dataset = {}  # 实际加载逻辑
        return dataset
    
    @abstractmethod
    def func(self):
        pass

class current_class(base):
    def func_B(self, dataset):
        # 逻辑B使用dataset.keys()
        keys = dataset.keys()
        # 编写逻辑B操作
        pass
    
    def func(self):
        dataset = self.func_A()
        self.func_B(dataset)

class another_class(base):
    def func(self):
        self.func_A()  # 仅执行逻辑A,忽略返回值

该方案代码更简洁,仅需在基类实现func_A,子类按需调用即可,返回值的轻微开销在多数场景下可忽略。

内容的提问来源于stack exchange,提问作者structuralengin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 16:00:59