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
相关产品推荐
相关产品推荐

