如何重写互相调用的两个方法,使super()调用时使用基类对应方法?
解决Python继承中父类方法调用子类重写方法的问题
嘿,这个问题我之前也踩过坑!核心原因是Python的动态方法绑定机制:当你在父类A的f1里调用self.f2()时,self始终指向当前的实例(也就是B的实例),所以会优先触发子类B里重写的f2,而不是父类A自己的f2。
下面给你两种靠谱的修改方案,按需选择:
方案1:固定父类方法调用自身的f2(最直接)
如果你希望A的f1不管被哪个子类调用,都只执行A自己的f2,那直接在A的f1里通过类名调用f2并传入self就行:
class A: def f1(self): # 明确调用A类的f2,绕过动态绑定 A.f2(self) def f2(self): print("执行A类的f2方法") class B(A): def f1(self): super().f1() def f2(self): print("执行B类的f2方法") # 测试效果 b = B() b.f1() # 输出:执行A类的f2方法
方案2:子类调用时临时切换f2(灵活场景)
如果只是在B调用super().f1()的这个场景下需要用A的f2,其他时候还要保留B的f2逻辑,可以临时替换实例的f2方法,调用完再恢复:
class A: def f1(self): self.f2() def f2(self): print("执行A类的f2方法") class B(A): def f1(self): # 先保存子类原本的f2方法 original_f2 = self.f2 # 临时把实例的f2替换成A类的f2(注意要绑定实例) self.f2 = A.f2.__get__(self, A) try: # 调用父类的f1,此时会用A的f2 super().f1() finally: # 不管是否出错,都恢复原来的f2 self.f2 = original_f2 def f2(self): print("执行B类的f2方法") # 测试 b = B() b.f1() # 输出:执行A类的f2方法 b.f2() # 输出:执行B类的f2方法(原有功能不受影响)
补充下原理
Python的方法调用是运行时绑定的,也就是说,self.f2()到底调用哪个类的方法,是在运行时根据self的实际类型决定的,而不是定义f1的类。所以默认情况下,只要self是B的实例,不管在哪调用self.f2(),都会用B的f2。上面的方案就是通过直接指定类调用,或者临时修改实例的方法绑定,来打破这个默认行为。
内容的提问来源于stack exchange,提问作者Ajit
相关产品推荐
相关产品推荐

