super()到底指向什么?

What does the super() point to on earth?

在post中,super()被描述为:describe super()

super() looks at the next class in the MRO (method resolution order, accessed with cls.__mro__) to call the methods.   

有些material甚至给出了更明确的定义: more clear definition on super()

def  super ( cls , inst ) : 
    mro = inst.__class__.mro( ) 
    return mro[mro.index( cls )  +  1 ]

创建多重继承class结构如下:

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))

mro 列表:

>>> happystate.__mro__
(<class '__main__.happystate'>, <class '__main__.state'>, <class '__main__.event'>, <class 'object'>)

happystate中的super()class会看MRO中的下一个class,就是state中的class状态。

x=happystate()
<super: <class 'happystate'>, <happystate object>>
<super: <class 'happystate'>, <happystate object>>

为什么super() in happystate class 指向自己而不是MRO列表中的下一个class----state?
如果 super() 指向 state,输出应为:

x=happystate()
<super: <class 'state'>, <state object>>
<super: <class 'state'>, <state object>>

super() returns 跟踪 MRO 中当前位置的 super class 实例。在 super 实例上调用方法时,super 在 MRO 中查找下一个 class 并调用该 class 上的方法。

也许这会有所帮助:

class state():
    def __init__(self):
        print('state.__init__')
        print(super())
        super().__init__()

class event():
    def __init__(self):
        print('event.__init__')
        print(super())
        super().__init__()

class happystate(state,event):
    def __init__(self):
        print('happystate.__init__')
        print(super())
        super().__init__()

print(happystate.mro())
x = happystate()

输出:

[<class '__main__.happystate'>, <class '__main__.state'>, <class '__main__.event'>, <class 'object'>]
happystate.__init__
<super: <class 'happystate'>, <happystate object>>  # currently in happystate of happystate object
state.__init__                                      # state is next
<super: <class 'state'>, <happystate object>>       # now in state of happystate object.
event.__init__                                      # event is next
<super: <class 'event'>, <happystate object>>       # now in event of happystate object

这也说明了在使用继承时,树中的所有classes都需要使用super()。即使 event 没有基础 class,缺少 super().__init__() 也不会在创建 happystate.

时调用 state.__init__

它不“指向”同一个 class,super 是它自己的 class:

>>> super
<class 'super'>

>>> class happystate(state,event):
...     def __init__(self):
...         print(super(), type(super()))
... 
>>> happystate()
<super: <class 'happystate'>, <happystate object>> <class 'super'>

所以你也可以在class之外使用它:

>>> super(happystate)
<super: <class 'happystate'>, NULL>

但是在 class 内部它有一些特殊的行为,所以让我们将它保存为一个实例变量,以便我们可以与它进行更多交互:

>>> 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

但这仍然不能告诉我们太多信息,所以让我们跳转 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.

所以在一天结束时 super 可以帮助您从父 class(es) 访问内容,而无需自己遍历 MRO,这意味着更清晰的代码。让我们使用这些新知识并稍微修改一下您的代码:

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()

现在让我们尝试使用修改后的代码:

>>> 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