深入理解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 相关文章推荐
Pyramid添加Middleware的方法实例
Nov 27 Python
python发送伪造的arp请求
Jan 09 Python
python使用邻接矩阵构造图代码示例
Nov 10 Python
python实现抖音视频批量下载
Jun 20 Python
Python统计纯文本文件中英文单词出现个数的方法总结【测试可用】
Jul 25 Python
Python 利用scrapy爬虫通过短短50行代码下载整站短视频
Oct 29 Python
OpenCV HSV颜色识别及HSV基本颜色分量范围
Mar 22 Python
python语言基本语句用法总结
Jun 11 Python
利用Python实现Shp格式向GeoJSON的转换方法
Jul 09 Python
Django CBV与FBV原理及实例详解
Aug 12 Python
如何利用pygame实现简单的五子棋游戏
Dec 29 Python
利用Python如何制作贪吃蛇及AI版贪吃蛇详解
Aug 24 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中使用Oracle数据库(2)
2006/10/09 PHP
PHP PDOStatement对象bindpram()、bindvalue()和bindcolumn之间的区别
2014/11/20 PHP
php压缩和解压缩字符串的方法
2015/03/14 PHP
Linux下编译redis和phpredis的方法
2016/04/07 PHP
php基于session锁防止阻塞请求的方法分析
2017/08/07 PHP
php实现数组中出现次数超过一半的数字的统计方法
2018/10/14 PHP
thinkPHP5.1框架中Request类四种调用方式示例
2019/08/03 PHP
使用Apache的rewrite
2021/03/09 Servers
控制打印时页眉角的代码
2007/02/08 Javascript
Javascript入门学习资料收集整理篇
2008/07/06 Javascript
轻轻松松学JS调试(不下载任何工具)
2010/04/14 Javascript
基于jquery的button默认enter事件(回车事件)。
2011/05/18 Javascript
使用Jquery实现每日签到功能
2015/04/03 Javascript
js跨域请求数据的3种常用的方法
2015/12/01 Javascript
基于jQuery仿淘宝产品图片放大镜特效
2020/10/19 Javascript
JavaScript学习笔记之数组随机排序
2016/03/23 Javascript
几句话带你理解JS中的this、闭包、原型链
2016/09/26 Javascript
js + css实现标签内容切换功能(实例讲解)
2017/10/09 Javascript
在nginx上部署vue项目(history模式)的方法
2017/12/28 Javascript
详解JavaScript事件循环机制
2018/09/07 Javascript
JQuery实现ajax请求的示例和注意事项
2018/12/10 jQuery
JavaScript深入V8引擎以及编写优化代码的5个技巧
2019/06/24 Javascript
Vue项目开发常见问题和解决方案总结
2020/09/11 Javascript
react使用antd表单赋值,用于修改弹框的操作
2020/10/29 Javascript
详细解读Python中的__init__()方法
2015/05/02 Python
python 实现Requests发送带cookies的请求
2021/02/08 Python
Merrell迈乐澳大利亚网站:购买户外登山鞋
2017/05/28 全球购物
武汉高蓝德国际.net机试
2016/06/24 面试题
行政人员岗位职责
2013/12/08 职场文书
自荐信格式简述
2014/01/25 职场文书
廉洁教育学习材料
2014/05/19 职场文书
2014年入党积极分子党校培训心得体会
2014/07/08 职场文书
校园游戏活动新闻稿
2014/10/15 职场文书
2014年教学工作总结
2014/11/13 职场文书
学习委员竞选稿
2015/11/20 职场文书
Python自动操作神器PyAutoGUI的使用教程
2022/06/16 Python