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

Python如何通过子类对象同时调用基类及重写版本的calc()方法

结论

完全可以通过子类对象同时调用基类方法及其重写版本。
你当前直接调用obj.calc()仅触发子类方法,是因为Python的类方法查找遵循子类优先规则:当子类定义了与父类同名的方法时,实例调用该方法会默认命中子类的重写版本,不会自动执行父类的同名逻辑。

具体实现方案

根据使用场景不同,有两种常用实现方式:

方案1:在子类重写方法内通过super()调用基类逻辑

如果你希望每次调用子类calc()时,自动按流程执行基类的calc()逻辑,直接在子类方法中使用super()引用基类方法即可,不需要修改外部调用代码。
修正后的可运行代码如下(注意原代码使用了random模块需要先导入):

import random

class A:
    def calc(self):
        a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
        b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
        c = a + b
        return c

class B(A):
    def calc(self):
        # 执行基类calc逻辑,获取基类方法返回值
        base_calc_result = super().calc()
        # 执行子类原有重写逻辑
        x = random.randint(10, 100)
        lst = [random.randint(5, 35) for i in range(x)]
        print("子类calc生成的列表:", lst)
        # 可根据需求选择是否返回基类与子类的执行结果
        return base_calc_result, lst

obj = B()
# 单次调用即可同时执行基类与子类的calc逻辑
base_res, sub_lst = obj.calc()
print("基类calc返回的合并列表:", base_res)

方案2:外部调用时显式指定执行基类方法

如果你不想修改子类B的原有代码,只是在需要的时候单独调用基类版本的calc(),可以直接通过基类名调用方法,手动将子类实例作为self参数传入即可:

import random

# 保留原有A、B类的定义无需修改
class A:
    def calc(self):
        a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
        b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
        c = a + b
        return c

class B(A):
    def calc(self):
        x = random.randint(10,100)
        lst = [random.randint(5,35) for i in range(x)]
        print("子类calc生成的列表:", lst)

obj = B()
# 单独调用子类重写版本
print("=== 执行子类重写的calc ===")
obj.calc()
# 单独调用基类版本的calc
print("=== 执行基类的calc ===")
base_result = A.calc(obj)
print(base_result)
方案选择参考
  • 若需要将基类逻辑作为子类方法流程的固定部分,优先选super()方案,外部调用无感知,代码可维护性更高
  • 若仅临时需要调用基类逻辑、不想改动子类原有实现,选外部显式调用基类方法的方案,灵活度更高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 18:31:01