I tried to understand multiple inheritance behaviour with Python, so I tried something but I have no idea why the output of my code is what it is. (I know that diamond inheritance is bad, but was interested to see what happens.)
class Base:
name = "Base"
def test(self):
print("I am", self.name)
class A(Base):
internal_name = "A"
def __init__(self):
self.name = "A"
super().__init__()
def test(self):
super().test()
print("Called from A")
class B(Base):
internal_name = "B"
def __init__(self):
self.name = "B"
super().__init__()
def test(self):
super().test()
print("Called from B")
class C(A, B):
def __init__(self):
self.name = "C"
A.__init__(self)
B.__init__(self)
def identify(self):
print("Internal name:", self.internal_name)
c = C()
c.test()
c.identify()
The output on running this code:
I am B
Called from B
Called from A
Internal name: A
What I expected to see as output:
C() calls the __init__ of C, thus sets the variable name to "C", and then calls A.__init__, thus I thought it would override self.name with "A", and then call Base.__init__(), not doing anything. Then the same with B, overriding self.name to "B".
I would either expect the output to either be
I am B
Called from A
I am B
Called from B
or just one call, but the part that "I am B" is printed once, but that "Called from" appears twice completely caught me unexpectedly. And then internal_name is "A" for some reason, even though I called B.init() second, and also it's only the second inherited from class. What is happening with that order?
super().__init__()solves the next method to call see this document docs.python.org/3/howto/mro.html#python-2-3-mro . Even though it is for very old Python 2.3 this is still the way the mro (Method Resolution Order) in Python works.A().__init__(), you are creating a newAobject and then calling its__init__method a second time; you are not affecting the current object at all.A.__init__(self), that fixed the self.name to be B. But the .test() call still is strange. Currently reading through that mro() stuff, did not know about it, so maybe that resolves it once I am done.A.__init__(self)andB.__init__(self)with one call tosuper().__init__()