深入理解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爬虫:通过关键字爬取百度图片
Feb 17 Python
关于python2 csv写入空白行的问题
Jun 22 Python
python面试题小结附答案实例代码
Apr 11 Python
python使用MQTT给硬件传输图片的实现方法
May 05 Python
10分钟用python搭建一个超好用的CMDB系统
Jul 17 Python
详解Python图像处理库Pillow常用使用方法
Sep 02 Python
Python networkx包的实现
Feb 14 Python
将pytorch转成longtensor的简单方法
Feb 18 Python
matplotlib 曲线图 和 折线图 plt.plot()实例
Apr 17 Python
在python image 中实现安装中文字体
May 16 Python
Python Pandas list列表数据列拆分成多行的方法实现
Dec 14 Python
python爬虫利用selenium实现自动翻页爬取某鱼数据的思路详解
Dec 22 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
Mysql的常用命令
2006/10/09 PHP
php5 apache 2.2 webservice 创建与配置(java)
2011/01/27 PHP
PHP设计模式之调解者模式的深入解析
2013/06/13 PHP
php通过正则表达式记取数据来读取xml的方法
2015/03/09 PHP
基于PHPexecl类生成复杂的报表表头示例
2016/10/14 PHP
phpStudy配置多站点多域名和多端口的方法
2017/09/01 PHP
PHP使用反向Ajax技术实现在线客服系统详解
2019/07/01 PHP
DOM和XMLHttpRequest对象的属性和方法整理
2012/01/04 Javascript
jQuery的Ajax的自动完成功能控件简要说明
2013/02/22 Javascript
浅析jquery的js图表组件highcharts
2014/03/06 Javascript
使用js Math.random()函数生成n到m间的随机数字
2014/10/09 Javascript
原生JavaScript实现滚动条效果
2020/03/24 Javascript
jQuery设置单选按钮radio选中/不可用的实例代码
2016/06/24 Javascript
JS中的==运算: [''] == false —>true
2016/07/24 Javascript
Javascript 链式作用域详细介绍
2017/02/23 Javascript
详解React 16 中的异常处理
2017/07/28 Javascript
每个 JavaScript 工程师都应懂的33个概念
2018/10/22 Javascript
详解vue中axios的使用与封装
2019/03/20 Javascript
Node.js实现批量下载图片简单操作示例
2020/01/18 Javascript
vue项目接口管理,所有接口都在apis文件夹中统一管理操作
2020/08/13 Javascript
原生js实现照片墙效果
2020/10/13 Javascript
vue切换菜单取消未完成接口请求的案例
2020/11/13 Javascript
vue实现购物车的小练习
2020/12/21 Vue.js
寻找网站后台地址的python脚本
2014/09/01 Python
python里大整数相乘相关技巧指南
2014/09/12 Python
Django项目中model的数据处理以及页面交互方法
2018/05/30 Python
pycharm创建scrapy项目教程及遇到的坑解析
2019/08/15 Python
python3 图片 4通道转成3通道 1通道转成3通道 图片压缩实例
2019/12/03 Python
Python3 A*寻路算法实现方式
2019/12/24 Python
CSS3 calc()会计算属性详解
2018/02/27 HTML / CSS
荷兰度假屋租赁网站:Aan Zee
2020/02/28 全球购物
现金会计岗位职责
2013/12/05 职场文书
信用社竞聘演讲稿
2014/05/16 职场文书
2014年酒店年度工作总结
2014/12/10 职场文书
爱鸟护鸟的宣传语
2015/07/13 职场文书
公安纪律作风整顿心得体会
2016/01/23 职场文书