AdvancePython-深入解读python继承中的super方法

1.super基本用法

在pyhont类的继承中,我们经常重写方法来覆盖父类的同名方法。但是如果我们想实现父类的方法,就需要用到super。
看一个例子:

class A:
    def __init__(self):
        print('A')

class B(A):
    def __init__(self):
        print('B')
        #super(B,self).__init__() python2的用法
        super().__init__()  #python3的用法

运行结果

在本例中,B继承A,在B的__init__方法中先打印出了自己的B,然后利用super调用了父类的__init__打印出了A(注:在python2和3中,调用super时有不同的形式)

2.具体应用场景

from threading import Thread
class MyThread(Thread):
    def __init__(self,name,user):
        self.user = user
        super().__init__(name=name)#可将构造函数交给了父类,让父类实例化--重用代码

在threading源码中,实际上已经实现了__init__函数,该函数里面有很多参数,包括name,我们的MyThread子类去继承它后,使用super().init(name=name)来将构造函数交给了父类,让父类去进行实例化,实际上这体现了代码重用。

我们都会觉得,super就是用来调用父类方法的,但是真的是这样吗?当涉及到多重继承(菱形继承)时,super的调用顺序是什么?

3.super本质上和父类并无关联

#基类
class A:
    def __init__(self):
        print('A')

class B(A):
    def __init__(self):
        print('B')
        super().__init__()  #python3

class C(A):
    def __init__(self):
        print('C')
        super().__init__()  #python3

class D(B,C):
    def __init__(self):
        print('D')
        super(D,self).__init__()  #python2

if __name__ == '__main__':
    d = D()
    #print(D.__mro__)

体现了这样一种继承关系:
多重继承
我们打印一下结果:
运行结果

可以看到,如果你认为 super 代表去调用父类的方法,那么打印完B本应该去打印它的父类A,但是却去打印了C,原因是,super 和父类没有实质性的关联,现在让我们搞清 super 是按什么方式运行的。

4.mro 列表

mro:方法解析顺序(Method Resolution Order, MRO)列表,在继承中,它代表了类继承的顺序,是一种在多重继承中用于确定方法搜索顺序的算法,该顺序是根据C3线性化算法来定义的
我们可以使用print(D.__mro__)来查看mro顺序:
mro顺序
mro遵循以下三个原则:

  • 子类会先于父类被检查
  • 多个父类会根据它们在列表中的顺序被检查
  • 如果对下一个类存在两个合法的选择,选择第一个父类
我们看一下super函数的原型:
super(cls, inst):
mro = inst.__class__mro()
return mro(mro.index(cls) + 1)
cls 代表类,inst 代表实例
super做了两件事情:
  • 获取mro列表
  • 然后返回列表中的下一个类

当使用 super(cls, inst) 时,Python 会在 inst 的 MRO 列表上搜索 cls 的下一个类
在我们上面的例子中,super(D,self).__init__(),D的下一个类是B,调到B的__init__先打印出B,再执行super().__init__() ,然后搜索mro中的下一个类,即C,打印出C并继续执行其__init__方法,而不是打印A!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值