python3 直接用super().方法名()
python2 用super(class,instance).方法名() # 参数是类名和实例名
super()调用父类(超类)的方法。
*************************************************************************************
super()在多重继承中
# -*- coding: utf-8 -*-
class A:
def aa(self):
print(11)
class B(A):
def aa(self):
print(22)
class C(B):
def aa(self):
print(33)
class D(C):
def aa(self):
print(44)
# super(D,self).aa()
super().aa()
d=D()
d.aa()
# 多重继承,super(),会先在父类中查找,如果有就调用
# 如果没有就查看爷爷类,一层一层找上去
class Base(object):
def __init__(self):
print("enter Base")
print("leave Base")
class A(Base):
def __init__(self):
print("enter A")
super(A, self).__init__()
print("leave A")
class B(Base):
def __init__(self):
print("enter B")
super(B, self).__init__()
print("leave B")
class C(A, B):
def __init__(self):
print("enter C")
super(C, self).__init__()
print("leave C")
c=C()
print(C.mro())
print(A.__class__)
****************************************************************************************************************************************
语法:super(type[, object-or-type])
- type -- 类。
- object-or-type -- 类,一般是 self
- 无返回值
super其实和父类没有实质性的guan关联
****************************************************************************************************************************************
MRO列表
方法解析顺序列表MRO代表了类继承的顺序;一个MRO列表就是合并了所有父类的MRO列表,并遵循一下三原则:
字类永远在父类前面;
如果有多个父类,会根据他们在列表中的顺序检查
如果对下一个类存在两个合法的选择,选择第一个父类
****************************************************************************************************************************************
super原理
super的工作原理如下:
def super(cls, inst):
mro = inst.__class__.mro()
return mro[mro.index(cls) + 1]
其中,cls代表类,inst代表实例,上面的代码做了两件事:
获取inst的MRO列表
查找cls在当前MRO列表中的index,并返回他的下一个类,即mro[index+1]
当你调用super(cls,inst)时,python会在inst的MRO列表中搜索cls的下一个类
现在,让我们回到前面的例子。
首先看类 C 的 __init__ 方法:
super(C, self).__init__()
这里的 self 是当前 C 的实例,self.__class__.mro() 结果是:
[__main__.C, __main__.A, __main__.B, __main__.Base, object]
可以看到,C 的下一个类是 A,于是,跳到了 A 的 __init__,这时会打印出 enter A,并执行下面一行代码:
super(A, self).__init__()
注意,这里的 self 也是当前 C 的实例,MRO 列表跟上面是一样的,搜索 A 在 MRO 中的下一个类,发现是 B,于是,跳到了 B 的 __init__,这时会打印出 enter B,而不是 enter Base。
整个过程还是比较清晰的,关键是要理解 super 的工作方式,而不是想当然地认为 super 调用了父类的方法。
***************************************************************************************************************************************