深入理解Python 关于supper 的 用法和原理


Posted in Python onFebruary 28, 2018

一、前言

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

二、代码

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

class A():
  def go(self):
    print ("go A go!")
  def stop(self):
    print ("stop A stop!")
  def pause(self):
    raise Exception("Not Implemented")
class B(A):
  def go(self):
    super(B, self).go()
    print ("go B go!")
class C(A):
  def go(self):
    super(C, self).go()
    print ("go C go!")
  def stop(self):
    super(C, self).stop()
    print ("stop C stop!")
class D(B,C):
  def go(self):
    super(D, self).go()
    print ("go D go!")
  def stop(self):
    super(D, self).stop()
    print ("stop D stop!")
  def pause(self):
    print ("wait D wait!")
class E(B,C):
  pass
a = 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()

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

step1:

几个概念:

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

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

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

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

step2:

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

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

step3:

个人理解:

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

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

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

简洁点的三个原则就是:

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

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

也不用跑了,答案如下:

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!
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

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

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

补充:

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

Python2 没有默认继承object

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

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

Python3  super().函数名()

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

class A:
  def __init__(self):
    self.n = 2
  def add(self, m):
    print('self is {0} @A.add'.format(self))
    self.n += m
class B(A):
  def __init__(self):
    self.n = 3
  def add(self, m):
    print('self is {0} @B.add'.format(self))
    super().add(m)
    print('newb')
    self.n += 3
class C(A):
  def __init__(self):
    self.n = 4
  def add(self, m):
    print('self is {0} @C.add'.format(self))
    super().add(m)
    print('newc')
    self.n += 4
class D(B, C):
  def __init__(self):
    self.n = 5
  def add(self, m):
    print('self is {0} @D.add'.format(self))
    super().add(m)
    self.n += 5
d = D()
d.add(2)
print(d.n)

总结

以上所述是小编给大家介绍的Python 关于supper 的 用法和原理,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python使用回溯法子集树模板解决迷宫问题示例
Sep 01 Python
Python实现将HTML转换成doc格式文件的方法示例
Nov 20 Python
详解Python_shutil模块
Mar 15 Python
PyQt4 treewidget 选择改变颜色,并设置可编辑的方法
Jun 17 Python
Python定时任务随机时间执行的实现方法
Aug 14 Python
python 解决cv2绘制中文乱码问题
Dec 23 Python
Python中的sys.stdout.write实现打印刷新功能
Feb 21 Python
python3中sys.argv的实例用法
Apr 24 Python
Python 判断时间是否在时间区间内的实例
May 16 Python
没编程基础可以学python吗
Jun 17 Python
python用字节处理文件实例讲解
Apr 13 Python
Python中使用Opencv开发停车位计数器功能
Apr 04 Python
TensorFlow实现RNN循环神经网络
Feb 28 #Python
python使用TensorFlow进行图像处理的方法
Feb 28 #Python
使用Python搭建虚拟环境的配置方法
Feb 28 #Python
Python OpenCV获取视频的方法
Feb 28 #Python
python实现多线程行情抓取工具的方法
Feb 28 #Python
Python 记录日志的灵活性和可配置性介绍
Feb 27 #Python
python定向爬取淘宝商品价格
Feb 27 #Python
You might like
PHPlet在Windows下的安装
2006/10/09 PHP
php下mysql数据库操作类(改自discuz)
2010/07/03 PHP
php网页标题中文乱码的有效解决方法
2014/03/05 PHP
PHP header()函数常用方法总结
2014/04/11 PHP
Mac下快速搭建PHP开发环境步骤详解
2019/05/05 PHP
最简单的js图片切换效果实现代码
2011/09/24 Javascript
Extjs4 消息框去掉关闭按钮(类似Ext.Msg.alert)
2013/04/02 Javascript
javascript判断是手机还是电脑访问网页的简单实例分享
2014/06/03 Javascript
JavaScript将XML转成JSON的方法
2015/03/12 Javascript
jQuery使用fadeout实现元素渐隐效果的方法
2015/03/27 Javascript
javascript实现类似百度分享功能的方法
2015/07/27 Javascript
js倒计时抢购实例
2015/12/20 Javascript
ionic js 复选框 与普通的 HTML 复选框到底有没区别
2016/06/06 Javascript
JavaScript 数据类型详解
2017/03/13 Javascript
js时间戳与日期格式之间转换详解
2017/12/11 Javascript
讲解vue-router之命名路由和命名视图
2018/05/28 Javascript
浅析前端路由简介以及vue-router实现原理
2018/06/01 Javascript
Element-ui中元素滚动时el-option超出元素区域的问题
2019/05/30 Javascript
vue+element项目中过滤输入框特殊字符小结
2019/08/07 Javascript
vue+koa2实现session、token登陆状态验证的示例
2019/08/30 Javascript
jQuery操作元素的内容和样式完整实例分析
2020/01/10 jQuery
vue 出现data-v-xxx的原因及解决
2020/08/04 Javascript
Javascript实现贪吃蛇小游戏(含详细注释)
2020/10/23 Javascript
python如何通过实例方法名字调用方法
2018/03/21 Python
Python 实现自动导入缺失的库
2019/10/29 Python
python实现字符串和数字拼接
2020/03/02 Python
CSS3实现可爱的小黄人动画
2016/07/11 HTML / CSS
美国班级戒指、帽子和礼服、毕业产品、年鉴:Balfour
2018/11/01 全球购物
彪马俄罗斯官网:PUMA俄罗斯
2019/07/13 全球购物
面料业务员岗位职责
2013/12/26 职场文书
面试后的英文感谢信
2014/02/01 职场文书
经典洗发水广告词
2014/03/13 职场文书
日语系毕业求职信
2014/07/27 职场文书
高校师德师风自我剖析材料
2014/09/29 职场文书
材料采购员岗位职责
2015/04/03 职场文书
分享几个JavaScript运算符的使用技巧
2021/04/24 Javascript