-3
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

Mark
  • 90,562
  • 7
  • 108
  • 148
  • 2
    Show error message as properly formatted text in the question, not as image or external link. – Michael Butscher Dec 14 '19 at 02:24
  • 3
    You somehow expect that `super()` magically uses the right base class that fits your call. Once from `B` and on the next line the same call should use `C`. – Klaus D. Dec 14 '19 at 02:29
  • 1
    Looks to me like the Deadly Diamond of Death of multiple inheritance. – Gunther Schadow Dec 14 '19 at 02:39
  • 2
    @GuntherSchadow: That's not actually a problem in Python with properly written cooperative inheritance. Using the C3 linearization algorithm to produce a consistent, complete, non-repeating order for the parent classes in the method resolution order allows for each super class method to be called precisely once, even in diamond inheritance patterns. – ShadowRanger Dec 14 '19 at 03:10

2 Answers2

0

The error is caused by the call to super().__init__(name) in the class B. Unlike single-inheritance languages such as Java, super() in Python doesn't necessarily give you the superclass; it gives you the next class in the method resolution order. The MRO for class D is this:

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

As you can see, the next class in the MRO after B is C, so the call to super().__init__(name) invokes C.__init__ with a single argument. However, the C.__init__ method expects two arguments, so calling it with just one argument results in the error you've seen.

kaya3
  • 47,440
  • 4
  • 68
  • 97
0

A resolution to this multiple inheritance is to cooperatively design the classes, see Raymond's article 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')

As pointed out by others, this will follow the MRO, e.g. D -> B -> C - A.

AChampion
  • 29,683
  • 4
  • 59
  • 75