5
In [5]: class a(object):
   ...:     def __init__(self):
   ...:         print "In class a"
   ...:         self.a = 1
   ...:         
In [6]: class b(object):
   ...:     def __init__(self):
   ...:         print "In class b"
   ...:         self.b = 2
   ...:         
   ...:         

In [7]: class c(b, a):
   ...:     pass
   ...: 
In [8]: c.mro()
Out[8]: 
[<class '__main__.c'>,
 <class '__main__.b'>,
 <class '__main__.a'>,
 <type 'object'>]

In [9]: obj = c()
In class b

In [10]: obj.__dict__
Out[10]: {'b': 2}

The default __init__ method of class c is called on obj creation, which internally calls the __init__ of only class b.

As per my understanding, if I inherit from 2 class, my derived class object should have variables from both class (unless they are private to those classes).

My Question: Am I wrong in expecting my derived object to contain variables from both classes? If so, why? Shouldn't __init__ of class a also be called? What would have happened in language like C++?

Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116
avasal
  • 14,350
  • 4
  • 31
  • 47
  • jcollado's answer is correct. See [this answer](http://stackoverflow.com/q/607186) for more detail on how `super` works. – perelman Feb 13 '12 at 07:24

1 Answers1

8

In python, initialization methods from upper classes aren't called by default. To do that, you have to explicitly call them using super as follows:

class a(object):
    def __init__(self):
        super(a, self).__init__()
        print "In class a"
        self.a = 1

class b(object):
    def __init__(self):
        super(b, self).__init__()
        print "In class b"
        self.b = 2

class c(b, a):
    pass

obj = c()

Example output.

In class a
In class b

Edit: Regarding why this works this way, I'd say that it's a design decision based on The Zen of of Python:

Explicit is better than implicit.

jcollado
  • 39,419
  • 8
  • 102
  • 133
  • why does `super(b, self).__init__()` call `__init__` method of a, a is not a superclass of b, does it mean the syntax calls next object in mro sequence? – avasal Feb 13 '12 at 08:03
  • @avasal, yes the `super` call will find the next available method in the mro sequence. Note that the code given only works because `object.__init__` exists and is called with no arguments: if the `__init__` in the classes took an argument, or you want to propogate another method then you may need an intervening stub class to terminate the chain of `super` calls. See also http://rhettinger.wordpress.com/2011/05/26/super-considered-super/ – Duncan Feb 13 '12 at 09:08