深入理解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中使用strip()方法删除字符串中空格的教程
May 20 Python
python压缩文件夹内所有文件为zip文件的方法
Jun 20 Python
Python搭建APNS苹果推送通知推送服务的相关模块使用指南
Jun 02 Python
使用Python编写一个最基础的代码解释器的要点解析
Jul 12 Python
机器学习python实战之决策树
Nov 01 Python
python实现媒体播放器功能
Feb 11 Python
Python continue继续循环用法总结
Jun 10 Python
使用selenium模拟登录解决滑块验证问题的实现
May 10 Python
Python matplotlib修改默认字体的操作
Mar 05 Python
使用tensorflow实现VGG网络,训练mnist数据集方式
May 26 Python
Python猫眼电影最近上映的电影票房信息
Sep 18 Python
Python通过getattr函数获取对象的属性值
Oct 16 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
用PHP调用数据库的存贮过程!
2006/10/09 PHP
php对数组排序代码分享
2014/02/24 PHP
PHP中empty和isset对于参数结构的判断及empty()和isset()的区别
2015/11/15 PHP
Zend Framework教程之Zend_Form组件实现表单提交并显示错误提示的方法
2016/03/21 PHP
php函数传值的引用传递注意事项分析
2016/06/25 PHP
PHP迭代与递归实现无限级分类
2017/08/28 PHP
静态图片的十一种滤镜效果--不支持Ie7及非IE浏览器。
2007/03/06 Javascript
验证码在IE中不刷新而谷歌等浏览器正常的解决方案
2014/03/18 Javascript
jQuery Migrate 1.1.0 Released 注意事项
2014/06/14 Javascript
jquery根据锚点offset值实现动画切换
2014/09/11 Javascript
javascript框架设计之框架分类及主要功能
2015/06/23 Javascript
js实现页面跳转的五种方法推荐
2016/03/10 Javascript
Bootstrap精简教程中秋大放送
2016/09/15 Javascript
关于JavaScript的单双引号嵌套问题
2017/08/20 Javascript
微信小程序实现banner图轮播效果
2020/06/28 Javascript
详解vue-cli3多环境打包配置
2019/03/28 Javascript
JavaScript 自定义html元素鼠标右键菜单功能
2019/12/02 Javascript
Python的函数嵌套的使用方法
2014/01/24 Python
python中__slots__用法实例
2015/06/04 Python
Python选课系统开发程序
2016/09/02 Python
python subprocess 杀掉全部派生的子进程方法
2017/01/16 Python
python 网络编程详解及简单实例
2017/04/25 Python
通过实例了解Python str()和repr()的区别
2020/01/17 Python
Keras loss函数剖析
2020/07/06 Python
JSP和EJB可以共享HttpSession么?EJB里面可以改变session里面的内容
2013/06/05 面试题
商务日语毕业生自荐信
2013/11/23 职场文书
施工人员岗位职责
2013/12/12 职场文书
专业技术职务聘任书
2014/03/29 职场文书
工程索赔意向书
2014/08/30 职场文书
个人向公司借款协议书
2014/10/09 职场文书
活动总结模板大全
2015/05/11 职场文书
浪漫的婚礼主持词
2015/06/30 职场文书
导游词之河北白洋淀
2020/01/15 职场文书
Golang 使用Map实现去重与set的功能操作
2021/04/29 Golang
Redis 哨兵集群的实现
2021/06/18 Redis
Android Flutter实现图片滑动切换效果
2022/04/07 Java/Android