NOTE_python_usage for ‘super‘

本文为精简笔记
参考链接:https://www.cnblogs.com/chenhuabin/p/10058594.html

super 是一个,实例化后得到的是一个代理的对象,而不是得到父类,并且我们使用这个对象来调用父类和兄弟类的方法。

原理

用法

super()
super(type , obj)
super(type_1 , type_2)

super(type, obj)

!!!!!!!!!!!!!!!!!!!!!极为重要!!!!!!!!!!!!!!!!!!!!
type:指出用继承顺序中的哪个元素。
obj(某个类的实例化对象):指出用哪个类的继承顺序

step1.根据_mro_(method resolution order方法解析顺序)机制理清类的继承顺序(注意: 不是输出顺序)。
step2.调用type对应的类在__mro__顺序中的下一个类的方法(该方法为super(type, obj).__init__中的init,或者super(type, obj).fun()的fun())。

realize step1:
class A(object):
    pass

class B(object):
    pass

class C(object):
    pass

class D(A,B):
    pass

class E(B, C):
    pass

class F(D, E):
    pass

print(F.__mro__)

输出元素顺序为:F->D->A->E->B->C->object
为何输出这样的顺序?
1.找入度为0的并且左侧优先的点。2.将该点拿出并将与之相连的箭头全部删除。3.所有点的拿出顺序就是继承顺序(不要忘了在结尾加上父类)。
在这里插入图片描述
当要生成F的继承顺序时,C3算法过程如下:首先将入度(指向该节点的箭头数量)为零的节点放入列表,并将F节点及与F节点有关的箭头从上图树中删除;继续找入度为0的节点,找到D和E,左侧优先,故而现将D放入列表,并从上图树中删除D,这是列表中就有了F、D。继续找入度为0的节点,有A和E满足,左侧优先,所以是A,将A从上图中取出放入列表,列表中顺序为F、D、E;接下来入度为0的节点只剩下E,取出E放入列表;只剩下B和C节点,且入度都为0,但左侧优先,二先将B放入列表,然后才是后才是C;不过别忘了,Python所有类都有一个共同的父类,那就是object类,所以,最好还会把object放入列表末尾。

realize step2

我们接着在上面的代码后接入下面的代码:

super(E , F()).fun() # 起始元素为E,F类继承元素顺序为:F->D->A->E->B->C->object,目标方法为fun(),输出结果:B.fun
super(D , F()).fun() # 输出结果:A.fun
super(F , F()).fun() # 输出结果:D.fun
super(B , F()).fun() # 输出结果:C.fun
super(B , E()).fun() # 输出结果:起始元素为E,E类继承元素顺序为:E->B->C->object,目标方法为fun(),C.fun
super(B , B()).fun() # 这是错误的,会报错

以及下面一段代码:

class A:
    def fun(self):
        print('A.fun')

class B(A):
    def fun(self):
        super(B , self).fun()
        print('B.fun')

class C(A):
    def fun(self):
        super(C , self).fun()
        print('C.fun')

class D(B , C):
    def fun(self):
        super(D , self).fun()
        print('D.fun')

D().fun()
#输出为
#A.fun
#C.fun
#B.fun
#D.fun

在这里插入图片描述
在这里插入图片描述
D类的__mro__顺序是D->B->C->A,在D类中调用fun方法,然后在D类fun方法中遇到super(D , self).fun(),这个self指的是D类的实例化对象,所以用的是D类的__mro__顺序,而且指明位置是D后面也就是B类,所以继续调用B类的fun方法,遇到super(B , self).fun(),这时候需要注意,这里的self还是原来的D类实例(千万注意不是B类实例),所以还是用D类的__mro__顺序,那就继续调用下一个C类的fun方法,同理继续调用下一个父类,也就是A类的fun方法,执行完A类的fun方法后,回到C的fun方法中,打印输出,然后回到B类的fun方法,直到D类的fun方法打印输出完。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值