python中super的作用

1.MRO

首先介绍mro(method resolution order)

若有代码

class A(object):
    pass

class B(A):
    pass

class C(B):
    pass

print(C.mro())

执行,输出结果为

[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]

此即为C类的继承关系。我们可以通过类的mro()方法来查看其mro链条,即C->B->A->Object

2.super引入

我们先感性地认识一下super。super是一个类,可看作:针对问题“如何在执行某个类的__init__方法时沿着mro链条继承之前类的__init__方法”提出。

光看这句话也许会糊涂,这里稍微说明一下

若有代码

class A(object):
    def __init__(self):
        print("A")
    pass

class B(A):
    def __init__(self):
        print("B")
    pass

class C(B):
    def __init__(self):
        print("C")
    pass

C()

执行,输出结果为

C

看见没有?C是由A,B一路继承而来,但在初始化时,只会执行自己的初始化方法,却不执行父类的初始化方法,这并不符合继承的有关理念,super可以用来解决该问题。

3.不使用super时

若有代码

class A(object):
    def __init__(self):
        print("A")
    pass

class B(A):
    def __init__(self):
        print("B")
    pass

class C(B):
    def __init__(self):
        B.__init__(self)
        A.__init__(self)
        print("C")
    pass

C()

执行,有

B
A
C

看见没有?我们直接在C的初始化方法里调用了B和A的初始化方法,也可以达成目的。但这种方法在继承关系更加复杂,以及某些情况下会出现一些问题,且代码不利于维护,因此我们采用super来更加优雅地解决该问题

4.super简介

在pycharm中输入super,指针放到super上,按ctrl+鼠标左键,即可看见super类的有关介绍

"""
    super() -> same as super(__class__, <first argument>)
    super(type) -> unbound super object
    super(type, obj) -> bound super object; requires isinstance(obj, type)
    super(type, type2) -> bound super object; requires issubclass(type2, type)
    Typical use to call a cooperative superclass method:
    class C(B):
        def meth(self, arg):
            super().meth(arg)
    This works for class methods too:
    class C(B):
        @classmethod
        def cmeth(cls, arg):
            super().cmeth(arg)
    """

看不懂没关系,下面简要说明:

super(参数一,参数二)会接收2个参数

从功能的角度来看,参数一决定指向的MRO链条的下一个节点,参数二决定MRO链条

从参数的类型来看 ,参数一填入类,参数二根据需要继承的方法可以①填入实例②填入类(分别对应实例方法、类方法),且会把参数二直接传入调用的函数(之后会有代码举例)

简单举个例子:若参数一填入C,参数二填入C。

则参数一决定了下一个节点为B,也就是说将要继承B中的某个方法。

而参数二不是决定MRO链条的吗?由于此处参数二为C,则可看作引入了链条C->B->A->Object。

从功能的角度来说,参数一限定得比较死板,因为它决定了你到底需要引入哪个函数的方法;而参数二相对灵活,因为参数二承担引入链条的作用,只要该引入的链条包含了参数一对应的类即可。(假如C还有一个子类D,则参数二也可以为D,因为此链条依然包含参数一的类,即A)

现在看一下代码举例(

class A(object):
    def __init__(self):
        print("A")
    pass

class B(A):
    def __init__(self):
        super(B,self).__init__()
        print("B")
    pass

class C(B):
    def __init__(self):
        super(C,self).__init__()
        print("C")
    pass

C()

输出结果为

A
B
C

可以看见,实现了预期目的

稍微提醒一下,这里super所属行的最后,__init__()括号中是没有参数的,因为正如之前所说,super的第二个参数会直接传入之后的调用方法之中

讲解到此结束,这是非常粗糙的理解,因为应用场景稍微变化,传入参数可能就需要有相应调整,读者应该将本教程视为对super的简单理解,需要自己动手才能进一步掌握super的用法

如有错误,欢迎指出,谢谢

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值