这种多重继承有什么问题?

时间:2019-12-14 02:22:08

标签: python multiple-inheritance diamond-problem

class A:

    def __init__(self,name):
        self.name=name

class B(A):

    def __init__(self,name,add):
        super().__init__(name)
        self.add = add

class C(A):

    def __init__(self,name,tel):
        super().__init__(name)
        self.tel = tel

class D(B,C):

    def __init__(self,name,add,tel,company):
        super().__init__(name,add)
        super().__init__(name,tel)
        self.company = company

d = D('Hank','ctm',55514,'google')

enter image description here

2 个答案:

答案 0 :(得分:0)

该错误是由于调用类super().__init__(name)中的B引起的。与Java等单继承语言不同,Python中的super()不一定会为您提供超类。它为您提供method resolution order中的下一个课程。类D的MRO是这样的:

>>> D.__mro__
(<class '__main__.D'>,
 <class '__main__.B'>,
 <class '__main__.C'>,
 <class '__main__.A'>,
 <class 'object'>)

如您所见,MRO中B之后的下一个类是C,因此对super().__init__(name)的调用将使用单个参数调用C.__init__。但是,C.__init__方法需要两个参数,因此仅使用一个参数调用它会导致您看到错误。

答案 1 :(得分:0)

对此多重继承的解决方法是共同设计类,请参见Raymond的文章Python’s super() considered super!

class A:
    def __init__(self, name, **kwargs):
        self.name = name

class B(A):
    def __init__(self, add, **kwargs):
        super().__init__(**kwargs)
        self.add = add

class C(A):
    def __init__(self, tel, **kwargs):
        super().__init__(**kwargs)
        self.tel = tel

class D(B, C):
    def __init__(self, company, **kwargs):
        super().__init__(**kwargs)
        self.company = company

d = D(name='Hank', add='ctm', tel=55514, company='google')

其他人指出,这将遵循MRO,例如D -> B -> C - A

相关问题