python3super原理_Python 关于super 的 用法和原理(挖坑)

https://www.cnblogs.com/xinghuaikang/p/8481712.html

一、前言

Python 面向对象中有继承这个概念,初学时感觉很牛逼,里面也有个super类,经常见到,最近做一些题才算是理解了。特地记录分享给后来研究的小伙伴,毕竟现在小学生都开始学了(滑稽脸)

二、代码

直接上干货,能把下面一个问题全答对,后面就不用看了。

48304ba5e6f9fe08f3fa1abda7d326ab.png

classA():

defgo(self):

print ("go A go!")

defstop(self):

print ("stop A stop!")

defpause(self):

raise Exception("Not Implemented")

classB(A):

defgo(self):

super(B, self).go()

print ("go B go!")

classC(A):

defgo(self):

super(C, self).go()

print ("go C go!")

defstop(self):

super(C, self).stop()

print ("stop C stop!")

classD(B,C):

defgo(self):

super(D, self).go()

print ("go D go!")

defstop(self):

super(D, self).stop()

print ("stop D stop!")

defpause(self):

print ("wait D wait!")

classE(B,C):

passa =A()

b =B()

c =C()

d =D()

e =E()

#说明下列代码的输出结果

a.go()

print('--------')

b.go()

print('--------')

c.go()

print('--------')

d.go()

print('--------')

e.go()

print('--------')

a.stop()

print('--------')

b.stop()

print('--------')

c.stop()

print('--------')

d.stop()

print('--------')

e.stop()

print(D.mro())

a.pause()

b.pause()

c.pause()

d.pause()

e.pause()

48304ba5e6f9fe08f3fa1abda7d326ab.png

当然,直接运行就有答案了,还是要仔细想一下,反正看到我第一次跑出的结果的时候,我都不敢相信自己的眼睛。

step1:

几个概念:

继承的功能:父类的代码重用

多态的功能:同一方法对不同类型的对象会有相应的结果

开闭原则:对扩展开放,对修改封闭

super类功能:新式类实现广度优先的不重复的调用父类,解决了钻石继承(多继承)的难题

step2:

super实现原理:通过c3算法,生成mro(method resolution order)列表,根据列表中元素顺序查询调用

新式类调用顺序为广度优先,旧式类为深度优先

step3:

个人理解:

1.调用了父类的方法,出入的是子类的实例对象

2.新式类子类(A,B),A就在B之前

3.super类似于嵌套的一种设计,当代码执行到super实例化后,先去找同级父类,若没有其余父类,再执行自身父类,再往下走,

简洁点的三个原则就是:

子类在父类前,所有类不重复调用,从左到右

理解了以上的说法,题目就没问题了。

也不用跑了,答案如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

a.go()#go A go!

b.go()#go A go!# go B go!

c.go()#go A go!# go C go!

d.go()#go A go!# go C go!# go B go!# go D go!

e.go()#go A go!# go C go!# go B go!

a.stop()#stop A stop!

b.stop()#stop A stop!

c.stop()#stop A stop!# stop C stop!

d.stop()#stop A stop!# stop C stop!# stop D stop!

e.stop()#stop A stop!stop C stop!

a.pause()#... Exception: Not Implemented

b.pause()#... Exception: Not Implemented

c.pause()#... Exception: Not Implemented

d.pause()#wait D wait!

e.pause()#...Exception: Not Implemented

48304ba5e6f9fe08f3fa1abda7d326ab.png

看了答案,其实还有一点,父类抛异常的情况,如果子类有不抛异常的方法,异常就不抛出了,这个设计也会很有用。

这里就中间一个A,C,B,D的和网上常见的不太一样,促使我仔细研究了一下,其实就是个人理解第三条。

补充:

Python2 和Python3在这个问题上的差别

Python2 没有默认继承object

Python3 默认全部继承object类,都是新式类

Python2super调用 super(开始类名,self).函数名()

Python3  super().函数名()

关于调用父类函数传入子类实例的栗子举一个:

48304ba5e6f9fe08f3fa1abda7d326ab.png

classA:

def __init__(self):

self.n = 2

defadd(self, m):

print('self is {0} @A.add'.format(self))

self.n +=m

classB(A):

def __init__(self):

self.n = 3

defadd(self, m):

print('self is {0} @B.add'.format(self))

super().add(m)

print('newb')

self.n += 3

classC(A):

def __init__(self):

self.n = 4

defadd(self, m):

print('self is {0} @C.add'.format(self))

super().add(m)

print('newc')

self.n += 4

classD(B, C):

def __init__(self):

self.n = 5

defadd(self, m):

print('self is {0} @D.add'.format(self))

super().add(m)

self.n += 5d =D()

d.add(2)

print(d.n)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值