深入理解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模拟新浪微博登陆功能(新浪微博爬虫)
Dec 24 Python
在Python的web框架中中编写日志列表的教程
Apr 30 Python
实例解析Python设计模式编程之桥接模式的运用
Mar 02 Python
python直接获取API传递回来的参数方法
Dec 17 Python
python print出共轭复数的方法详解
Jun 25 Python
python UDP(udp)协议发送和接收的实例
Jul 22 Python
使用Python的datetime库处理时间(RPA流程)
Nov 24 Python
Python爬虫爬取煎蛋网图片代码实例
Dec 16 Python
关于初始种子自动选取的区域生长实例(python+opencv)
Jan 16 Python
通过python实现windows桌面截图代码实例
Jan 17 Python
Python sqlite3查询操作过程解析
Feb 20 Python
详解torch.Tensor的4种乘法
Sep 03 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中遍历stdclass object的实现代码
2011/06/09 PHP
PHP获取当前url的具体方法全面解析
2013/11/26 PHP
php使用filter过滤器验证邮箱 ipv6地址 url验证
2013/12/25 PHP
为何说PHP引用是个坑,要慎用
2018/04/02 PHP
javascript 基础篇3 类,回调函数,内置对象,事件处理
2012/03/14 Javascript
防止xss和sql注入:JS特殊字符过滤正则
2013/04/18 Javascript
JS实现关键字搜索时的相关下拉字段效果
2014/08/05 Javascript
node.js中的fs.appendFile方法使用说明
2014/12/17 Javascript
js获取当前日期前七天的方法
2015/02/28 Javascript
JS使用正则表达式除去字符串中重复字符的方法
2015/11/05 Javascript
如何使用headjs来管理和异步加载js
2016/11/29 Javascript
ES6中Class类的静态方法实例小结
2017/10/28 Javascript
微信小程序tabbar底部导航
2018/11/05 Javascript
JS字符串与二进制的相互转化实例代码详解
2019/06/28 Javascript
vue-cli 为项目设置别名的方法
2019/10/15 Javascript
jQuery HTML css()方法与css类实例详解
2020/05/20 jQuery
Array.filter中如何正确使用Async
2020/11/04 Javascript
python使用psutil模块获取系统状态
2016/08/27 Python
Python获取文件所在目录和文件名的方法
2017/01/12 Python
Python3.6 Schedule模块定时任务(实例讲解)
2017/11/09 Python
详解利用Python scipy.signal.filtfilt() 实现信号滤波
2019/06/05 Python
python 字典操作提取key,value的方法
2019/06/26 Python
Pandas时间序列:重采样及频率转换方式
2019/12/26 Python
Python键鼠操作自动化库PyAutoGUI简介(小结)
2020/05/17 Python
基于django micro搭建网站实现加水印功能
2020/05/22 Python
Python使用configparser读取ini配置文件
2020/05/25 Python
pytorch掉坑记录:model.eval的作用说明
2020/06/23 Python
tensorflow 2.1.0 安装与实战教程(CASIA FACE v5)
2020/06/30 Python
canvas绘制文本内容自动换行的实现代码
2019/01/14 HTML / CSS
资深生产主管自我评价
2013/09/22 职场文书
中专生自荐信
2013/10/12 职场文书
函授自我鉴定
2013/11/06 职场文书
室内设计专业学生的自我评价分享
2013/11/27 职场文书
计划生育责任书
2015/05/09 职场文书
2016中秋晚会开幕词
2016/03/03 职场文书
MongoDB数据库的安装步骤
2021/06/18 MongoDB