• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Python中的super()面向对象编程

    Python super()面向对象编程

    一、为什么要用 super()

    当子类重写了父类方法时,又想调用父类的同名方法时,就需要用到 super()

    二、什么是 super

    三、继承中使用 super

    1、实例方法使用 super

    类图

    实际代码

    class A:
        def __init__(self):
            self.n = 1
    
        def add(self, m):
            print(f'AAA [self] is {id(self)}')
            print(f'AAA [self.n] is {self.n}')
            self.n += m
    
    
    class B(A):
        def __init__(self):
            self.n = 100
    
        # 重写父类方法
        def add(self, m):
            # 子类特有代码
            print(f'BBB [self] is {id(self)}')
            print(f'BBB [self.n] is {self.n}')
    
            # 调用父类方法
            super().add(m)
    
            self.n += m
    
    
    b = B()
    b.add(2)
    print(b.n)
    
     
    
    # 输出结果
    BBB [self] is 4489158560
    BBB [self.n] is 100
    
    AAA [self] is 4489158560
    AAA [self.n] is 100
    
    104
    
    

    super().add()  的确调用了父类方法
    重点:此时父类方法的 self 并不是父类实例对象,而是子类实例对象

    2、构造方法使用 super

    class Animal:
        def __init__(self, name):
            self.name = name
    
        def prints(self):
            print("Animale name is ", self.name)
    
    
    class Dog(Animal):
        def __init__(self, name, age):
            # 调用父类的 init 构造方法
            super(Dog, self).__init__(name)
            self.age = age
    
        def prints(self):
            # 调用父类的方法
            super(Dog, self).prints()
            print("Dog age is ", self.age)
    
    
    dog = Dog("小汪", 10)
    dog.prints()
    
     
    
    # 输出结果
    Animale name is  小汪
    Dog age is  10
    
    

    这里用了 super(子类名, self) ,和上面的 super() 是一样效果

    调用父类方法有两种方式

    其实还有第三种

    在 Python  2.x 的时候,如果需要调用父类的方法,还可以用

    父类名.方法(self)

    通过父类名调用父类方法(不推荐)

    class Animal:
        def __init__(self, name):
            self.name = name
    
        def prints(self):
            print("Animale name is ", self.name)
    
    
    class Dog(Animal):
        def __init__(self, name, age):
            # 调用父类的 init 构造方法
            Animal.__init__(self, name)
            self.age = age
    
        def prints(self):
            # 调用父类的方法
            Animal.prints(self)
            print("Dog age is ", self.age)
    
    
    dog = Dog("小汪", 10)
    dog.prints()
    
    
    # 输出结果
    Animale name is  小汪
    Dog age is  10
    
    

    通过父类名调用的这种方式,是需要传 self 参数的哦

    温馨提示:
    在开发时, 父类名.方法() super().方法() 两种方式不要混用哈

    灵魂拷问一:既然已经重写了子类的构造方法,为什么还要去调用 super?
    子类需要重写父类方法来实现子类独有的功能,但同时又需要依赖父类方法来完成某些逻辑

    实际栗子

    from threading import Thread
    
    
    class MyThread(Thread):
        def __init__(self, name):
            # 1、实现子类独有功能
            print("子类线程 %s" % name)
            # 2、需要依赖父类方法完成其他功能
            super().__init__(name=name)
    

    四、多继承中使用 super

    类图

    实际代码

    # 多继承
    class Animal:
        def __init__(self, animalName):
            print(animalName, 'is an animal.')
    
    
    # Mammal 继承 Animal
    class Mammal(Animal):
        def __init__(self, mammalName):
            print(mammalName, 'is a mammal.')
            super().__init__(mammalName)
    
    
    # CannotFly 继承 Mammal
    class CannotFly(Mammal):
        def __init__(self, mammalThatCantFly):
            print(mammalThatCantFly, "cannot fly.")
            super().__init__(mammalThatCantFly)
    
    
    # CannotSwim 继承 Mammal
    class CannotSwim(Mammal):
        def __init__(self, mammalThatCantSwim):
            print(mammalThatCantSwim, "cannot swim.")
            super().__init__(mammalThatCantSwim)
    
    
    # Cat 继承 CannotSwim 和 CannotFly
    class Cat(CannotSwim, CannotFly):
        def __init__(self):
            print('I am a cat.');
            super().__init__('Cat')
    
    
    # Driver code
    cat = Cat()
    print('')
    bat = CannotSwim('Bat')
    
     
    
    # 输出结果
    I am a cat.
    Cat cannot swim.
    Cat cannot fly.
    Cat is a mammal.
    Cat is an animal.
    
    Bat cannot swim.
    Bat is a mammal.
    Bat is an animal.
    
    

    好像挺奇怪的,从输出结果看,为什么 CannotSwim 类里面的 super().__init__() 调用的是 CannotFly 类里面的方法呢?不是应该调用 CannotSwim 的父类 Mamal 的方法吗?

    灵魂拷问二:super 的执行顺序到底是什么?

    先来看看 Cat 的 MRO

    print(Cat.__mro__)
    
    (class '__main__.Cat'>, class '__main__.CannotSwim'>, class '__main__.CannotFly'>, class '__main__.Mammal'>, class '__main__.Animal'>, class 'object'>)
    

    从 Cat 的 MRO 可以看到

    多继承的栗子二

    实际代码

    class A:
        def __init__(self):
            self.n = 2
    
        def add(self, m):
            # 第四步
            # 来自 D.add 中的 super
            # self == d, self.n == d.n == 5
            print('self is {0} @AAA.add'.format(self))
            self.n += m
            # d.n == 7
    
    
    class C(A):
        def __init__(self):
            self.n = 4
    
        def add(self, m):
            # 第三步
            # 来自 B.add 中的 super
            # self == d, self.n == d.n == 5
            print('self is {0} @CCC.add'.format(self))
            # 等价于 suepr(C, self).add(m)
            # self 的 MRO 是 [D, B, C, A, object]
            # 从 C 之后的 [A, object] 中查找 add 方法
            super().add(m)
    
            # 第五步
            # d.n = 7
            self.n += 4
            # d.n = 11
    
    
    class B(A):
        def __init__(self):
            self.n = 3
    
        def add(self, m):
            # 第二步
            # 来自 D.add 中的 super
            # self == d, self.n == d.n == 5
            print('self is {0} @BBB.add'.format(self))
            # self 的 MRO 是 [D, B, C, A, object]
            # 从 B 之后的 [C, A, object] 中查找 add 方法
            # 从 C 找 add 方法
            super().add(m)
    
            # 第六步
            # d.n = 11
            self.n += 3
            # d.n = 14
    
    
    class D(B, C):
        def __init__(self):
            self.n = 5
    
        def add(self, m):
            # 第一步
            print('self is {0} @DDD.add'.format(self))
            # self 的 MRO 是 [D, B, C, A, object]
            # 从 D 之后的 [B, C, A, object] 中查找 add 方法
            # 从 B 找 add 方法
            super().add(m)
    
            # 第七步
            # d.n = 14
            self.n += 5
            # self.n = 19
    
    
    d = D()
    d.add(2)
    print(d.n)
     
    
    

    先看看 D 类的 MRO

    print(D.__mro__)
    
    (class '__main__.D'>, class '__main__.B'>, class '__main__.C'>, class '__main__.A'>, class 'object'>)
    

    输出结果

    self is __main__.D object at 0x10c14a190> @DDD.add
    self is __main__.D object at 0x10c14a190> @BBB.add
    self is __main__.D object at 0x10c14a190> @CCC.add
    self is __main__.D object at 0x10c14a190> @AAA.add
    19
    

    调用顺序的确是 D、B、C、A

    执行顺序

    class D(B, C):          class B(A):            class C(A):             class A:
    def add(self, m):       def add(self, m):      def add(self, m):       def add(self, m):
    super().add(m)  1.--->  super().add(m) 2.--->  super().add(m)  3.--->  self.n += m
     self.n += 5   ------6. self.n += 3    ----5. self.n += 4     ----4. --|
    (14+5=19)               (11+3=14)              (7+4=11)                (5+2=7)
     
    
    

    执行顺序图


    到此这篇关于Python super()面向对象编程的文章就介绍到这了,更多相关Python super()内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    您可能感兴趣的文章:
    • python中super()函数的理解与基本使用
    • 详解python的super()的作用和原理
    • Python类的继承super相关原理解析
    • python super()函数的基本使用
    • Python类super()及私有属性原理解析
    • Python super()函数使用及多重继承
    • Python super()方法原理详解
    • python super函数使用方法详解
    • python super用法及原理详解
    • python类中super() 的使用解析
    • 使用 Supervisor 监控 Python3 进程方式
    • Python高级编程之继承问题详解(super与mro)
    • Python 继承,重写,super()调用父类方法操作示例
    • python3中类的继承以及self和super的区别详解
    上一篇:Python 经典贪心算法之Prim算法案例详解
    下一篇:Python字典中items()函数案例详解
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Python中的super()面向对象编程 Python,中的,super,面向,对象,