深入理解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 相关文章推荐
pycharm 使用心得(六)进行简单的数据库管理
Jun 06 Python
python将MongoDB里的ObjectId转换为时间戳的方法
Mar 13 Python
使用Python的urllib和urllib2模块制作爬虫的实例教程
Jan 20 Python
快速了解Python相对导入
Jan 12 Python
selenium+python 去除启动的黑色cmd窗口方法
May 22 Python
Python编程在flask中模拟进行Restful的CRUD操作
Dec 28 Python
Python项目 基于Scapy实现SYN泛洪攻击的方法
Jul 23 Python
你可能不知道的Python 技巧小结
Jan 29 Python
Python中常用的高阶函数实例详解
Feb 21 Python
django 链接多个数据库 并使用原生sql实现
Mar 28 Python
django在开发中取消外键约束的实现
May 20 Python
Python简单实现词云图代码及步骤解析
Jun 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
从Web查询数据库之PHP与MySQL篇
2009/09/25 PHP
微盾PHP脚本加密专家php解密算法
2020/09/13 PHP
解析php中array_merge与array+array的区别
2013/06/21 PHP
ThinkPHP5.1表单令牌Token失效问题的解决
2019/03/22 PHP
js实现双向链表互联网机顶盒实战应用实现
2011/10/28 Javascript
通过action传过来的值在option获取进行验证的方法
2013/11/14 Javascript
JS判断变量是否为空判断是否null
2014/07/25 Javascript
jQuery EasyUI实现右键菜单变灰不可用效果
2015/09/24 Javascript
表单验证插件Validation应用的实例讲解
2015/10/10 Javascript
JavaScript简单遍历DOM对象所有属性的实现方法
2015/10/21 Javascript
详解js私有作用域中创建特权方法
2016/01/25 Javascript
javascript中对象的定义、使用以及对象和原型链操作小结
2016/12/14 Javascript
原生js实现放大镜效果
2017/01/11 Javascript
js实现适合新闻类图片的轮播效果
2017/02/05 Javascript
使用AngularJS2中的指令实现按钮的切换效果
2017/03/27 Javascript
基于JavaScript实现移动端无限加载分页
2017/03/27 Javascript
js中的 || 与 && 运算符详解
2018/05/24 Javascript
详解axios中封装使用、拦截特定请求、判断所有请求加载完毕)
2019/04/09 Javascript
关于angular引入ng-zorro的问题浅析
2020/09/09 Javascript
vue+flask实现视频合成功能(拖拽上传)
2021/03/04 Vue.js
[01:20]DOTA2更新全新英雄 天涯墨客现已加入游戏
2018/08/25 DOTA
深入理解Javascript中的this关键字
2015/03/27 Python
python模块之StringIO使用示例
2015/04/08 Python
python json.loads兼容单引号数据的方法
2018/12/19 Python
Django 内置权限扩展案例详解
2019/03/04 Python
Python matplotlib学习笔记之坐标轴范围
2019/06/28 Python
django 数据库连接模块解析及简单长连接改造方法
2019/08/29 Python
python模拟实现斗地主发牌
2020/01/07 Python
前端面试必备之CSS3的新特性
2017/09/05 HTML / CSS
中国领先的专业家电网购平台:国美在线
2016/12/25 全球购物
全球地下的服装和态度:Slam Jam
2018/02/04 全球购物
Amara德国:家居饰品、设计师品牌和豪华礼品
2019/05/20 全球购物
村道德模范事迹材料
2014/08/28 职场文书
个人典型事迹材料
2014/12/30 职场文书
2015年街道办事处工作总结
2015/05/22 职场文书
Python实现数据的序列化操作详解
2022/07/07 Python