In the post ,super() was described as: describe super()
super() looks at the next class in the MRO (method resolution order, accessed with cls.__mro__) to call the methods.
Some material even give a more clear definition as: more clear definition on super()
def super ( cls , inst ) :
mro = inst.__class__.mro( )
return mro[mro.index( cls ) + 1 ]
Create a multiple inheritnce class struture as below:
class state():
def __init__(self):
pass
class event():
def __init__(self):
pass
class happystate(state,event):
def __init__(self):
print(super())
print(super(happystate,self))
The mro list :
>>> happystate.__mro__
(<class '__main__.happystate'>, <class '__main__.state'>, <class '__main__.event'>, <class 'object'>)
The super()
in happystate
class will look at the next class in the MRO, it is state
class in this status.
x=happystate()
<super: <class 'happystate'>, <happystate object>>
<super: <class 'happystate'>, <happystate object>>
Why super()
in happystate
class point to itself instead of the next class in MRO list----state
?
If super()
point to state
,the output should be as:
x=happystate()
<super: <class 'state'>, <state object>>
<super: <class 'state'>, <state object>>
It doesn't "point" to the same class, super
is a class of its own:
>>> super
<class 'super'>
>>> class happystate(state,event):
... def __init__(self):
... print(super(), type(super()))
...
>>> happystate()
<super: <class 'happystate'>, <happystate object>> <class 'super'>
So you can also use it outside the class:
>>> super(happystate)
<super: <class 'happystate'>, NULL>
But inside the class it has some special behavior, so let's save it as an instance variable so we can interact with it a bit more:
>>> class happystate(state,event):
... def __init__(self):
... self.s = super()
...
>>> h = happystate()
>>> h.s.__self_class__
<class '__main__.happystate'>
>>> h.s.__thisclass__
<class '__main__.happystate'> # the class
>>> h.s.__self__
<__main__.happystate object at 0x7fa8a42642e0> # the object of the class
But that still doesn't tell us much, so let's jump at the docs for super:
Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class.
So at the end of the day super
is there to help you access stuff from the parent class(es) without having to traverse the MRO yourself, which means cleaner code. Let's use this newfound knowledge and modify your code a bit:
class state():
def __init__(self, x):
print("state __init__", x)
self.x = x
class event():
def __init__(self):
print("event __init__")
class happystate(state,event):
def __init__(self):
super(state, self).__init__()
self.s = super()
Now let's try using the modified code:
>>> h = happystate()
event __init__ # surprise! It doesn't call `state`
# (or its super - `object`) but the
# next in the MRO for `happystate`: `event`!
>>> h.s.__init__(3) # calls state.__init__ (notice that we pass 1 argument)
state __init__ 3
>>> h.x # state.__init__ received `h` as the `self` argument and updated it!
3