This means that in the line super().__init__()
, super()
is returning the current object which is then implicitly passed to the superclass' __init__()
method. Is this accurate or am I missing something here?
>>> help(super)
super() -> same as super(__class__, )
super
call returns a proxy/wrapper object which remembers:
The instance invoking super()
The class of the calling object
The class that's invoking super()
This is perfectly sound. super
always fetches the attribute of the next class in the hierarchy ( really the MRO) that has the attribute that you're looking for. So it's not returning the current object, but rather and more accurately, it returns an object that remembers enough information to search for attributes higher in the class hierarchy.
- What exactly is being passed to
__init__()
and how? We are calling it on super()
so whatever this is returning should be getting passed to the __init__()
method from what I understand about Python so far.
You're almost right. But super
loves to play tricks on us. super
class defines __getattribute__
, this method is responsible for attribute search. When you do something like: super().y()
, super.__getattribute__
gets called searching for y
. Once it finds y
it passes the instance that's invoking the super
call to y
. Also, super
has __get__
method, which makes it a descriptor, I'll omit the details of descriptors here, refer to the documentation to know more. This answers your second question as well, as to why self
isn't passed explicitly.
*Note: super
is a little bit different and relies on some magic. Almost for all other classes, the behavior is the same. That is:
a = A() # A is a class
a.y() # same as A.y(a), self is a
But super
is different:
class A:
def y(self):
return self
class B(A):
def y(self)
return super().y() # equivalent to: A.y(self)
b = B()
b.y() is b # True: returns b not super(), self is b not super()