I have read Expert Python Programming which has an example for multi-inheritance. The book author has explained but I did not understand it, so I would like to have another view.
The example shows that object B
is created two times!
Could you please give me an intuitive explanation.
In [1]: class A(object):
...: def __init__(self):
...: print "A"
...: super(A, self).__init__()
In [2]: class B(object):
...: def __init__(self):
...: print "B"
...: super(B, self).__init__()
In [3]: class C(A,B):
...: def __init__(self):
...: print "C"
...: A.__init__(self)
...: B.__init__(self)
In [4]: print "MRO:", [x.__name__ for x in C.__mro__]
MRO: ['C', 'A', 'B', 'object']
In [5]: C()
C
A
B
B
Out[5]: <__main__.C at 0x3efceb8>
The book author said:
This happens due to the
A.__init__(self)
call, which is made with the C instance, thus makingsuper(A, self).__init__()
callB
's constructor
The point from which I didn't get its idea is how A.__init__(self)
call will make super(A, self).__init__()
call B
's constructor
The __new__() is a static method of the object class. When you create a new object by calling the class, Python calls the __new__() method to create the object first and then calls the __init__() method to initialize the object's attributes.
Python __add__() function is one of the magic methods in Python that returns a new object(third) i.e. the addition of the other two objects. It implements the addition operator “+” in Python.
As all of us know, Python supports multiple inheritance, what means, in Python, a class can inherit features and attributes from multiple classes.
Comparing Equality With the Python == and !=Use the equality operators == and != if you want to check whether or not two objects have the same value, regardless of where they're stored in memory.
The super()
just means "next in line", where the line is the mro ['C', 'A', 'B', 'object']
. So next in line for A
is B
.
The mro is calculated according to an algorithm called C3 linearization.
When you use super()
, Python just goes along this order. When you write your class A
you don't know yet which class will be next in line. Only after you create your class C
with multiple inheritance and run your program you will get the mro and "know" what will be next for A
.
For your example it means:
C()
calls the __init__()
of C
, in which it calls the __init__()
of A
. Now, A
uses super()
and finds B
in the mro, hence it calls the __init__()
of B
. Next, the __init__()
of C
calls the __init__()
of B
again.
Calling super()
in the __init__()
creates a different mro and avoids the double call to the __init__()
of B
.
from __future__ import print_function
class A(object):
def __init__(self):
print("A")
super(A, self).__init__()
class B(object):
def __init__(self):
print("B")
super(B, self).__init__()
class C(A,B):
def __init__(self):
print("C")
super(C, self).__init__()
Use:
>>> C.mro()
[__main__.C, __main__.A, __main__.B, object]
>> C()
C
A
B
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With