python中super()方法的理解
python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,
有时候还会有一个参数cls(相当于类名,当直接调用类方法的时候使用)。
python2中super()的用法:
super(class,self).__init__()
python3中super()的用法:
super().__init__()
在类的继承里面super()非常常用, 它解决了子类调用父类方法的一些问题, 父类多次被调用时只执行一次。
def super(cls, inst):
mro = inst.__class__.mro()
return mro[mro.index(cls) + 1]
当使用 super(cls, inst) 时,Python 会在 inst 的类的 MRO 列表上搜索 cls 的下一个类。
而查看inst类的的MRO列表的方法就是:
类.mro() 或 类.__mro__ 或 inst.__class__.mro()
例如:当C是一个类的时候,获得一个类的MRO的方法是
C.mro() 或 C.__mro__ 或 C().__class__.mro()
执行过程:
当执行生成D的inst对象的时候,先执行Enter D
这个时候D类的MRO列表为[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
当执行super(D,self) 就是在self对象的类的MRO列表中查找D的下一个父类。这个self是D类的实例对象inst。
而D类中的MRO列表中D的下一个父类是B。
例如:
1、super单继承的时候:
class A:
def __init__(self):
self.n = 2
def add(self, m):
print('self is {0} @A.add'.format(self))
self.n += m
class B(A):
def __init__(self):
self.n = 3
def add(self, m):
print('self is {0} @B.add'.format(self))
super().add(m)
self.n += 3
b = B()
b.add(2)
print(b.n)
结果是什么呢?
为什么是8?
执行b.add(2)的时候,执行A中的add()函数,执行的时候这个时候的self是b这个实例,所以这个self.n是3
所以执行3+2=5
然后执行super的下一句5+3=8。
2、super多继承的时候
#super的多继承
class A:
def __init__(self):
self.n = 2
def add(self, m):
print('self is {0} @A.add'.format(self))
self.n += m
class B(A):
def __init__(self):
self.n = 3
def add(self, m):
print('self is {0} @B.add'.format(self))
super().add(m)
self.n += 3
class C(A):
def __init__(self):
self.n = 4
def add(self, m):
print('self is {0} @C.add'.format(self))
super().add(m)
self.n += 4
class D(B, C):
def __init__(self):
self.n = 5
def add(self, m):
print('self is {0} @D.add'.format(self))
super().add(m)
self.n += 5
d = D()
d.add(2)
print(d.n)
这个结果是什么呢?
我认为是5+B.add+C.add+A.add+5=5+3+4+2+5=19
看下输出的结果:
执行过程是什么样的呢?
详细的代码分析如下: