美文网首页
11.详解python中super()函数原理及常用实例

11.详解python中super()函数原理及常用实例

作者: 软件开发技术修炼 | 来源:发表于2022-05-04 20:03 被阅读0次

    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
    

    相关文章

      网友评论

          本文标题:11.详解python中super()函数原理及常用实例

          本文链接:https://www.haomeiwen.com/subject/owkiyrtx.html