Reputation: 105
Why does calling Parent classes with super() does not work while using 'direct' call works fine?
class A(object):
def __init__(self, x):
self.x = x
print("Inside A __init__. x = %s" % self.x)
class B(object):
def __init__(self, y):
self.y = y
print("Inside B __init__. y = %s" % self.y)
class C(A,B):
def __init__(self, z):
super(C, self).__init__(6)
super(C, self).__init__(5)
#1. A.__init__(self,6)
#2. B.__init__(self,5)
self.z = z
print("Inside C __init__. z = %s" % self.z)
if __name__ == "__main__":
log = C(2)
With uncommented 'super' the result I am getting is:
Inside A __init__. x = 6
Inside A __init__. x = 5
Inside C __init__. z = 2
so the code for 'B' class init is never called. But after using the commented lines '#1', and '#2' the code works as it should:
Inside A __init__. x = 6
Inside B __init__. y = 5
Inside C __init__. z = 2
Questions:
Upvotes: 2
Views: 172
Reputation: 530920
An answer, which should rather be considered an example of how super
works rather than how to actually write code:
class A(object):
def __init__(self, x):
self.x = x
print("Inside A __init__. x = %s" % self.x)
class B(object):
def __init__(self, y):
self.y = y
print("Inside B __init__. y = %s" % self.y)
class C(A,B):
def __init__(self, z):
super(C, self).__init__(6)
super(A, self).__init__(5)
self.z = z
print("Inside C __init__. z = %s" % self.z)
if __name__ == "__main__":
log = C(2)
Each class has a method resolution order (MRO), which is used when looking up inherited functions. For C
, that order is
>>> C.__mro__
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>)
super(foo, bar)
provides a reference to (really, a proxy for) the next class after foo
in the MRO of type(bar)
. super(C, self)
provides a reference (really, a proxy) to A
, so that A.__init__
is the resulting call. super(A, self)
, however, provides a proxy to B
, resulting in a call to B.__init__
.
The general rule, though, is that you really don't know what method will be called next, since you don't necessarily know the type of self
(it could be a instance of a descendent class with a different MRO than an instance of C
). To use super
properly, you need to ensure that all potential classes are using it, so that methods will always be dispatched properly.
Upvotes: 3