Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

An Object is created twice in Python

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 making super(A, self).__init__() call B'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

like image 492
Bryan Avatar asked Feb 25 '16 12:02

Bryan


People also ask

What does the __ New__ method do?

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.

What is __ add __?

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.

Can an object have two classes Python?

As all of us know, Python supports multiple inheritance, what means, in Python, a class can inherit features and attributes from multiple classes.

Are two objects the same Python?

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.


1 Answers

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
like image 140
Mike Müller Avatar answered Sep 22 '22 15:09

Mike Müller