super(),在类的继承里面super()非常常用,解决了子类调用父类同名方法的一些问题,父类多次被调用时只执行一次,优化了执行逻辑;
用来解决多重继承问题的,直接用类名调用父类方法在单继承中没问题,如使用多继承,则涉及到查找顺序、重复调用等问题;
MRO就是类的方法解析顺序表,继承父类方法时的顺序表
语法 super(type[,object-or-type])
type--类,object-or-type--类,一般是self
1. super()函数原理
class A:
def add(self, x):
y = x+1
print(y)
class B(A):
def add(self, x):
# A.add(self,x) # 修改了父类名称,那么在子类中会涉及多处修改
super().add(x)
b = B()
b.add(2)
#输出:
3
运行发现:super().add(x) 与A.add(self,x)执行结果一致;但涉及多继承,发现super()只调用一次
2. super()机制
在super机制里可以保证公共父类仅被执行一次,至于执行的顺序,是按照MRO(Method Resolution Order):方法解析顺序 进行的
class A:
def __init__(self):
print("Enter A") # 不使用super(),每次调用Enter A,Leave A
print("Leave A") # 使用super(),只调用一次
class B(A):
def __init__(self):
print("Enter B")
#A.__init__(self)
super(B, self).__init__()
print("Leave B")
class C(A):
def __init__(self):
print("Enter C")
#A.__init__(self)
super(C, self).__init__() # 使用super()
print("Leave C")
class E(C,B):
def __init__(self):
print("Enter E")
#B.__init__(self)
#C.__init__(self)
super(E, self).__init__() # 使用super()
print("Leave E")
E()
# 使用super()输出:
Enter E
Enter C
Enter B
Enter A
Leave A
Leave B
Leave C
Leave E
#不使用super()输出:
Enter E
Enter B
Enter A
Leave A
Leave B
Enter C
Enter A
Leave A
Leave C
Leave E
MRO执行顺序
3. super()函数实例
super()可以调用父类中的任何方法,超(父类的父类)类的任何方法;可重写父类同名的init函数,及其他方法
class FooParent(object):
def __init__(self):
self.parent = 'I\'m the parent.'
print('Parent')
def bar(self,message):
print("%s from Parent" % message)
class FooChild(FooParent):
def __init__(self):
# super(FooChild,self)首先找到 FooChild 的父类(就是类FooParent),然后把类FooChild 的对象转换为类FooParent的对象
super().__init__()
print('Child')
def bar(self,message):
super().bar(message)
print('Child bar fuction')
print(self.parent)
if __name__ == '__main__':
fooChild = FooChild()
fooChild.bar('HelloWorld')
# 结果:
Parent
Child
HelloWorld from Parent
Child bar fuction
I'm the parent.
4. 实例说明:子类传参给父类方法,args, kwargs的应用场景
在任何时候继承类和重写方法的,我们应当用到args, kwargs将接收到的位置参数和键值参数给父类方法
class Model(object):
def __init__(self,name):
self.name = name
def save(self,f_update = False,f_insert=False):
if f_update:
print("2")
if f_insert:
print("5")
# 构造一个新类,这个类继承Model,满足一定条件可以保存类的对象;这个新类继承Model,并重写Model的save()
class ChileM(Model):
def save(self,*args,**kwargs):
if self.name == 'abcd':
#子类ChileM的save()接受任何父类save()需要的参数,并传给父类方法
super(ChileM, self).save(*args,**kwargs)
else:
return None
c = ChileM('abcd')
c.save(f_update=True)
c.save(f_insert=True)
# 输出:
2
5
网友评论