super()干了啥
super()继承
转自:https://www.cnblogs.com/silencestorm/p/8404046.html
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__() # 等同于python3: super().__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()
print(C.mro())
"""
Enter C
Enter A
Enter B
Enter Base
Leave Base
Leave B
Leave A
Leave C
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>]
"""
每一个类,都有一个 MRO(Method Resolution Order) 列表。这是python 搜索属性和方法时的顺序。可以通过 class.mro()
或 obj.__class__.mro()
来查看。
>>> A.mro()
[<class '__main__.A'>, <class '__main__.Base'>, <class 'object'>]
super()的原理
:
def super(class,instance):
mro = instance.__class__.mro()
return mro[mro.index(class)+1] # 返回的是当前 instance 的 mro 列表中的 class索引+1 的类
所以上面代码执行顺序:
line 24: 实例化 C 类
line 21: 执行 C() 实例的 mro 中index=1的类 A
line 9: 此时 super(A, self).__init__() 中的 self,代表的是 C类实例,所以下一步执行 C实例 mro 中的 类B
line 15: 此时的 self 还是 C实例,所以根据mro顺序,下一步执行mro中的 Base类
简而言之,super 可以按照 mro 顺序,找到父类,然后将父类的某个方法,绑定给当前子类的实例,可以让子类调用这个方法:
下面这个例子,子类 B 重写了父类 A 的 abc(),但是我们依然可以调用父类的 abc(),
class A():
def abc(self):
# print(self) # 2. 打印一下 self 这个实例,会发现是类 B 的实例
return 'abc from A'
class B(A):
def abc(self):
print('abc from B')
def xyz(self):
x = super(B, self).abc() # 1. 找到父类的 abc 方法,并使用代理模式,让 self 这个实例可以执行这个方法
print("x is:", x)
print('xyz from B')
b = B()
b.xyz()