Python继承:调用父类方法后如何让后续调用栈沿用父类方法?
当然可行!咱们先搞清楚为什么现在输出是2,再一步步解决问题。
首先看你当前代码的执行流程:当你调用c.f()时,会进入Child.f(),这里用super()调用了Parent.g()。但Parent.g()里的self.h(),这个self还是你的Child实例啊!所以Python会优先找Child中重写的h(),自然输出2。
要实现让父类方法里的后续调用都走父类自己的实现,有几种靠谱的办法:
方法一:父类方法显式调用自身实现(最简单直接)
修改Parent的方法,直接用类名来调用自己的方法,而不是通过self。这样不管self是什么类型的实例,都会强制执行父类的版本:
class Parent(object): def f(self): Parent.g(self) # 明确调用Parent的g方法 def g(self): Parent.h(self) # 明确调用Parent的h方法 def h(self): print(1) class Child(Parent): def f(self): super(Child, self).g() def g(self): self.h() def h(self): print(2) c = Child() c.f() # 现在输出1
方法二:用上下文管理器临时切换实例类型(不修改父类的首选)
如果你不想改动父类的代码,可以写一个简单的上下文管理器,在执行父类方法的期间,临时把实例的类型改成Parent,执行完再恢复原样:
class TempClassSwitch: def __init__(self, instance, target_class): self.instance = instance self.original_class = instance.__class__ self.target_class = target_class def __enter__(self): self.instance.__class__ = self.target_class return self.instance def __exit__(self, exc_type, exc_val, exc_tb): self.instance.__class__ = self.original_class class Parent(object): def f(self): self.g() def g(self): self.h() def h(self): print(1) class Child(Parent): def f(self): with TempClassSwitch(self, Parent): super(Child, self).g() # 这段代码执行时,self的类型是Parent def g(self): self.h() def h(self): print(2) c = Child() c.f() # 输出1
这个方法的好处是对原有代码侵入性极小,而且执行完后实例的类型会恢复,不会影响后续的其他调用。
额外说明:为什么不能只靠super?
很多人会想,能不能在父类方法里用super()来强制调用父类的实现?其实如果是单继承的话,super(Parent, self).h()其实就是object.h(),但object没有h方法,所以会报错。所以这种场景下,显式指定类名或者临时切换实例类型是更可靠的方案。
内容的提问来源于stack exchange,提问作者The Dude
相关产品推荐
相关产品推荐

