如何在Python孙子类中继承多个父类的__init__方法及其他方法?
解决Python多继承中Grandchild类继承多个子类的初始化问题
首先,你的代码存在几个问题需要修正:
Grandchild.__init__里的Child2.__init__(self,name.lastname,s)是语法错误,应该写成name, lastname- 直接调用两个子类的
__init__会导致Parent.__init__被执行两次(每个子类的__init__都调用了super().__init__) info方法中使用super().getsname()会报错,因为super()在Grandchild中指向Child1,而Child1没有getsname方法
下面提供两种正确的实现方式:
方式一:利用MRO和super()优雅实现(推荐)
通过给父类的__init__添加**kwargs参数,让参数沿着MRO链传递,避免重复初始化Parent:
class Parent: def __init__(self, name, lastname, **kwargs): self.name = name self.lastname = lastname # 继续传递剩余参数给MRO链的下一个类 super().__init__(**kwargs) def getname(self): return "{} {}".format(self.name, self.lastname) class Child1(Parent): def __init__(self, age, **kwargs): self.age = age # 传递剩余参数给父类 super().__init__(**kwargs) def getnage(self): return [super().getname(), self.age] class Child2(Parent): def __init__(self, s, **kwargs): self.s = s # 传递剩余参数给父类 super().__init__(**kwargs) def getsname(self): return [super().getname(), self.s] class Grandchild(Child1, Child2): def __init__(self, name, lastname, age, s, address): self.address = address # 通过super()触发整个MRO链的初始化,自动传递所有参数 super().__init__(name=name, lastname=lastname, age=age, s=s) def info(self): # 直接通过self调用继承来的方法,无需super() return [self.getnage()[0], self.getnage()[1], self.getsname()[1], self.address]
说明:
- 每个类的
__init__只处理自己需要的参数,剩余参数通过**kwargs传递给MRO链的下一个类 Parent的__init__只会被执行一次,符合DRY原则Grandchild可以直接调用Child1和Child2的方法,因为多继承会把这些方法纳入自己的命名空间
方式二:显式调用子类的__init__(适合无法修改父类的场景)
如果不能修改Child1和Child2的代码,可修正语法错误后显式调用两个子类的__init__,虽然会重复执行Parent.__init__,但因为赋值的是相同属性,结果不受影响:
class Parent: def __init__(self,name,lastname): self.name = name self.lastname = lastname def getname(self): return "{} {}".format(self.name,self.lastname) class Child1(Parent): def __init__(self,name,lastname,age): self.age = age super().__init__(name,lastname) def getnage(self): return [super().getname(),self.age] class Child2(Parent): def __init__(self,name,lastname,s): self.s = s super().__init__(name,lastname) def getsname(self): return [super().getname(), self.s] class Grandchild(Child1,Child2): def __init__(self,name,lastname,age,s,address): self.address = address # 修正语法错误,显式调用两个子类的初始化方法 Child1.__init__(self,name,lastname,age) Child2.__init__(self,name,lastname,s) def info(self): # 直接用self调用继承的方法 return [self.getnage()[0], self.getnage()[1], self.getsname()[1], self.address]
关键修正点:
- 把
name.lastname改为name, lastname,修复语法错误 - 用
self.getsname()替代super().getsname(),避免找不到方法的错误
内容的提问来源于stack exchange,提问作者Dinesh Chahar
相关产品推荐
相关产品推荐

