Python3深入理解super()函数

前言

深入理解super()函数在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用super()函数来实现。

描述

  • super() 函数是用于调用父类(超类)的一个方法。
  • super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。
  • MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表。

语法

super(type[, object-or-type])

参数:

  • type – 类。
  • object-or-type – 类,一般是 self
class A:
    def __init__(self):
        print("A")


class B(A):
    def __init__(self):
        print("B")
        super().__init__()      # 调用父类


if __name__ == '__main__':
    b = B()

输出结果:

B
A			# super调用父类输出 A

单继承方式

class Animal:  # 创建动物类
    """动物类"""

    def __init__(self, name):  # 初始化方法
        self.name = name

    def eat(self):  # 定义吃食物方法
        print('%s正在吃食物' % self.name)

    def play(self):  # 定义玩耍方法
        print('%s正在玩' % self.name)

    def sleep(self):  # 定义休息方法
        print('%s正在休息' % self.name)


class Dog(Animal):
    """狗类"""

    def __init__(self, name):
        super().__init__(name)              # 定义基类的初始化方法
        print('这是一只%s' % self.name)

    def eat(self):                          # 定义狗吃食物的方法
        print('%s正在吃狗粮' % self.name)

    def bark(self):                         # 定义狗叫的方法
        print('%s会汪汪叫' % self.name)


dog = Dog('哈士奇')                        # 创建动物类的实例
dog.eat()                                 # 调用吃食物的方法
dog.play()                                # 调用玩耍的方法
dog.bark()                                # 调用狗叫的方法

输出结果:

这是一只哈士奇
哈士奇正在吃狗粮
哈士奇正在玩
哈士奇会汪汪叫

根据运行结果看出第21行代码因为调用了super().init()方法,并传递了一个name参数。在Animal基类的__init__方法中,将name赋值给self.name。所以第22行代码会输出“这是一只哈士奇”。

多继承方式

class Food:
    """实物类"""

    def __init__(self, name):
        print('%s是食物' % name)


class Vegetables(Food):
    """蔬菜类"""

    def __init__(self, Vname):
        print('%s是蔬菜' % Vname)
        super().__init__(Vname)


class Fruit(Food):
    """水果类"""

    def __init__(self, Fname):
        print('%s是水果' % Fname)
        super().__init__(Fname)


class Tomato(Fruit, Vegetables):
    """西红柿类"""
    def __init__(self):
        print('西红柿即是蔬菜又是水果')
        super().__init__('西红柿')


print(Tomato.__mro__)		# MRO 列表顺序
tomato = Tomato()           # 实例化西红柿类


输出结果:

(<class '__main__.Tomato'>, <class '__main__.Fruit'>, <class '__main__.Vegetables'>, <class '__main__.Food'>, <class 'object'>)
西红柿即是蔬菜又是水果
西红柿是水果
西红柿是蔬菜
西红柿是食物

根据运行结果可知:

  • super函数执行顺序是根据MRO列表的顺序。
  • super()其实和父类没有实质性的关联,只是在单继承的情况下,super()获得的类刚好是父类。
  • super()等价于super(cls,inst)获得的是cls类在inst实例的MRO列表中的下一个类。

总结

  • super()与父类没有实质性的关联
  • super()获取的是MRO列表中下一个类
发布了29 篇原创文章 · 获赞 19 · 访问量 1314

猜你喜欢

转载自blog.csdn.net/s1156605343/article/details/104695063