深入理解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中isalnum()方法的使用
May 18 Python
asyncio 的 coroutine对象 与 Future对象使用指南
Sep 11 Python
关于反爬虫的一些简单总结
Dec 13 Python
Python实现发送与接收邮件的方法详解
Mar 28 Python
详解python单元测试框架unittest
Jul 02 Python
Python内存读写操作示例
Jul 18 Python
python语音识别实践之百度语音API
Aug 30 Python
python常用函数与用法示例
Jul 02 Python
python 处理微信对账单数据的实例代码
Jul 19 Python
python使用正则来处理各种匹配问题
Dec 22 Python
Python restful框架接口开发实现
Apr 13 Python
利用Python实现学生信息管理系统的完整实例
Dec 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
咖啡常见的种类
2021/03/03 新手入门
一个颜色轮换的简单例子
2006/10/09 PHP
php中使用$_REQUEST需要注意的一个问题
2013/05/02 PHP
php中的常用魔术方法总结
2013/08/02 PHP
利用PHP函数计算中英文字符串长度的方法
2014/11/11 PHP
php运行提示:Fatal error Allowed memory size内存不足的解决方法
2014/12/17 PHP
php获取图片信息的方法详解
2015/12/10 PHP
php metaphone()函数的定义和用法
2016/05/15 PHP
ThinkPHP 模板substr的截取字符串函数详解
2017/01/09 PHP
js列举css中所有图标的实现代码
2011/07/04 Javascript
jQuery不间断滚动效果(模拟百度新闻支持文字/图片/垂直滚动)
2013/02/05 Javascript
js动态设置鼠标事件示例代码
2013/10/30 Javascript
全面解析JavaScript里的循环方法之forEach,for-in,for-of
2020/04/20 Javascript
JavaScript简单下拉菜单特效
2016/09/13 Javascript
vue删除html内容的标签样式实例
2018/09/13 Javascript
浅谈React Event实现原理
2018/09/20 Javascript
手把手教你如何使用nodejs编写cli命令行
2018/11/05 NodeJs
使用vue自定义指令开发表单验证插件validate.js
2019/05/23 Javascript
深入理解Vue keep-alive及实践总结
2019/08/21 Javascript
详解从vue-loader源码分析CSS Scoped的实现
2019/09/23 Javascript
Python虚拟环境Virtualenv使用教程
2015/05/18 Python
Python中exit、return、sys.exit()等使用实例和区别
2015/05/28 Python
机器学习经典算法-logistic回归代码详解
2017/12/22 Python
Python 字符串与二进制串的相互转换示例
2018/07/23 Python
python 返回列表中某个值的索引方法
2018/11/07 Python
pycharm运行程序时看不到任何结果显示的解决
2020/02/21 Python
详解基于Jupyter notebooks采用sklearn库实现多元回归方程编程
2020/03/25 Python
分布式全文检索引擎ElasticSearch原理及使用实例
2020/11/14 Python
css3制作动态进度条以及附加jQuery百分比数字显示
2012/12/13 HTML / CSS
毕业自荐书
2013/12/09 职场文书
最新大学职业规划书范文
2013/12/30 职场文书
2014年教师业务学习材料
2014/05/12 职场文书
爱心捐款感谢信
2015/01/20 职场文书
故意伤害辩护词
2015/05/21 职场文书
SQLServer中JSON文档型数据的查询问题解决
2021/06/27 SQL Server
解决Mysql的left join无效及使用的注意事项说明
2021/07/01 MySQL