深入理解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  __getattr__与__setattr__使用方法
Sep 06 Python
Python计算一个文件里字数的方法
Jun 15 Python
python实现requests发送/上传多个文件的示例
Jun 04 Python
浅谈django rest jwt vue 跨域问题
Oct 26 Python
Python Numpy库安装与基本操作示例
Jan 08 Python
Python-copy()与deepcopy()区别详解
Jul 12 Python
python3安装crypto出错及解决方法
Jul 30 Python
python实现PID算法及测试的例子
Aug 08 Python
python 解决print数组/矩阵无法完整输出的问题
Feb 19 Python
Django xadmin安装及使用详解
Oct 26 Python
Django model class Meta原理解析
Nov 14 Python
pytorch 实现变分自动编码器的操作
May 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
2020显卡排行榜天梯图 显卡天梯图2020年3月最新版
2020/04/02 数码科技
PHP中如何判断AJAX提交的数据
2012/02/05 PHP
gd库图片下载类实现下载网页所有图片的php代码
2012/08/20 PHP
php和javascript之间变量的传递实现代码
2012/12/19 PHP
php屏蔽错误及提示的方法
2020/05/10 PHP
表单切换,用回车键替换Tab健(不支持IE)
2011/07/20 Javascript
仅Firefox中链接A无法实现模拟点击以触发其默认行为
2011/07/31 Javascript
javascript权威指南 学习笔记之javascript数据类型
2011/09/24 Javascript
子窗体与父窗体传值示例js代码
2013/08/01 Javascript
JavaScript判断访问的来源是手机还是电脑,用的哪种浏览器
2013/12/12 Javascript
js中精确计算加法和减法示例
2014/03/28 Javascript
jQuery使用之设置元素样式用法实例
2015/01/19 Javascript
谈谈impress.js初步理解
2015/09/09 Javascript
原生js实现淘宝放大镜效果
2020/10/28 Javascript
微信小程序如何实现radio单选框单击打勾和取消
2020/01/21 Javascript
package.json各个属性说明详解
2020/03/11 Javascript
antd日期选择器禁止选择当天之前的时间操作
2020/10/29 Javascript
Python中用Ctrl+C终止多线程程序的问题解决
2013/03/30 Python
Python实现的数据结构与算法之队列详解
2015/04/22 Python
Python自动调用IE打开某个网站的方法
2015/06/03 Python
浅谈scrapy 的基本命令介绍
2017/06/13 Python
django模板语法学习之include示例详解
2017/12/17 Python
python: line=f.readlines()消除line中\n的方法
2018/03/19 Python
python实现将excel文件转化成CSV格式
2018/03/22 Python
Python SMTP配置参数并发送邮件
2020/06/16 Python
python字典通过值反查键的实现(简洁写法)
2020/09/30 Python
Web前端绘制0.5像素的几种方法
2017/08/11 HTML / CSS
数学系个人求职信范文
2014/01/30 职场文书
学习方法演讲稿
2014/05/10 职场文书
经济贸易专业自荐信
2014/06/11 职场文书
保护地球的标语
2014/06/17 职场文书
党员目标管理责任书
2014/07/25 职场文书
合伙经营协议书范本(通用版)
2014/12/03 职场文书
2015元旦晚会主持词(开场白+结束语)
2014/12/14 职场文书
学习习近平主席讲话心得体会
2016/01/20 职场文书
导游词之山东红叶谷
2019/10/31 职场文书