深入理解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的pandas工具包,保存.csv文件时不要表头的实例
Jun 14 Python
Python线性拟合实现函数与用法示例
Dec 13 Python
一篇文章彻底搞懂Python中可迭代(Iterable)、迭代器(Iterator)与生成器(Generator)的概念
May 13 Python
Python API 自动化实战详解(纯代码)
Jun 11 Python
基于python判断目录或者文件代码实例
Nov 29 Python
Django后台管理系统的图文使用教学
Jan 20 Python
tensorflow如何继续训练之前保存的模型实例
Jan 21 Python
Python 实现加密过的PDF文件转WORD格式
Feb 04 Python
logging level级别介绍
Feb 21 Python
详解Python中import机制
Sep 11 Python
详解用 python-docx 创建浮动图片
Jan 24 Python
Python使用Kubernetes API访问集群
May 30 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引用效率问题分析
2012/03/23 PHP
PHP ADODB生成下拉列表框功能示例
2018/05/29 PHP
php 使用 __call实现重载功能示例
2019/11/18 PHP
JavaScript 设计模式学习 Singleton
2009/07/27 Javascript
JS解析XML的实现代码
2009/11/12 Javascript
JavaScript字符串插入、删除、替换函数使用示例
2013/07/25 Javascript
Js base64 加密解密介绍
2013/10/11 Javascript
javascript中数组array及string的方法总结
2014/11/28 Javascript
详解JavaScript正则表达式之RegExp对象
2015/12/13 Javascript
基于Javascript实现二级联动菜单效果
2016/03/04 Javascript
如何在Angular.JS中接收并下载PDF
2016/11/26 Javascript
EasyUI Combobox设置默认值 获取text的方法
2016/11/28 Javascript
bootstrap中的 form表单属性role="form"的作用详解
2017/01/20 Javascript
JS常见算法详解
2017/02/28 Javascript
javascript实现数据双向绑定的三种方式小结
2017/03/09 Javascript
js Date()日期函数浏览器兼容问题解决方法
2017/09/12 Javascript
JavaScript实现创建自定义对象的常用方式总结
2018/07/09 Javascript
electron中使用bootstrap的示例代码
2018/11/06 Javascript
微信小程序 image组件遇到的问题
2019/05/28 Javascript
vue 使用外部JS与调用原生API操作示例
2019/12/02 Javascript
Python类的基础入门知识
2008/11/24 Python
Python 遍历子文件和所有子文件夹的代码实例
2016/12/21 Python
python的xpath获取div标签内html内容,实现innerhtml功能的方法
2019/01/02 Python
使用批处理脚本自动生成并上传NuGet包(操作方法)
2019/11/19 Python
canvas绘制太极图的实现示例
2020/04/29 HTML / CSS
iHerb中文官网:维生素、保健品和健康产品
2018/11/01 全球购物
大学校园活动策划书
2014/02/04 职场文书
工伤赔偿协议书
2014/04/15 职场文书
校企合作协议书
2014/04/16 职场文书
小学模范班主任事迹材料
2014/05/13 职场文书
售房委托书
2014/08/30 职场文书
教师四风对照检查材料思想汇报
2014/09/17 职场文书
新教师教学工作总结
2015/08/12 职场文书
课题研究阶段性总结
2015/08/13 职场文书
python删除csv文件的行列
2021/04/06 Python
Mysql如何实现不存在则插入,存在则更新
2022/03/25 MySQL