深入理解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 相关文章推荐
在Windows服务器下用Apache和mod_wsgi配置Python应用的教程
May 06 Python
python求质数的3种方法
Sep 28 Python
python3 pygame实现接小球游戏
May 14 Python
Python使用itchat模块实现简单的微信控制电脑功能示例
Aug 26 Python
Python可变参数会自动填充前面的默认同名参数实例
Nov 18 Python
python实现超市商品销售管理系统
Nov 22 Python
django框架ModelForm组件用法详解
Dec 11 Python
Django Haystack 全文检索与关键词高亮的实现
Feb 17 Python
python利用paramiko实现交换机巡检的示例
Sep 22 Python
python 实现倒计时功能(gui界面)
Nov 11 Python
Python实现PS滤镜中的USM锐化效果
Dec 04 Python
python读取pdf格式文档的实现代码
Apr 01 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读取xml方法介绍
2013/01/12 PHP
php制作unicode解码工具(unicode编码转换器)代码分享
2013/12/24 PHP
PH P5.2至5.5、5.6的新增功能详解
2014/07/14 PHP
PHP 二维array转换json的实例讲解
2018/08/21 PHP
Javascript匿名函数的一种应用 代码封装
2010/06/27 Javascript
改写一个简单的菜单 弹性大小
2010/12/02 Javascript
各种常用的JS函数整理
2013/10/25 Javascript
Egret引擎开发指南之编译项目
2014/09/03 Javascript
推荐一个自己用的封装好的javascript插件
2015/01/29 Javascript
BootStrap的Datepicker控件使用心得分享
2016/05/25 Javascript
微信小程序 form组件详解
2016/10/25 Javascript
原生js仿淘宝网商品放大镜效果
2017/02/28 Javascript
基于JavaScript实现移动端无限加载分页
2017/03/27 Javascript
Vue项目中引入外部文件的方法(css、js、less)
2017/07/24 Javascript
微信web端后退强制刷新功能的实现代码
2018/03/04 Javascript
setTimeout时间设置为0详细解析
2018/03/13 Javascript
vue基于element的区间选择组件
2018/09/07 Javascript
在实例中重学JavaScript事件循环
2020/12/03 Javascript
[02:15]2014DOTA2国际邀请赛 专访LGD.lin小兔子是大腿
2014/07/14 DOTA
python实现查询IP地址所在地
2015/03/29 Python
Python随手笔记第一篇(2)之初识列表和元组
2016/01/23 Python
Python基于列表list实现的CRUD操作功能示例
2018/01/05 Python
Python用for循环实现九九乘法表
2018/05/31 Python
Python Flask框架扩展操作示例
2019/05/03 Python
Python使用百度翻译开发平台实现英文翻译为中文功能示例
2019/08/08 Python
python实现抠图给证件照换背景源码
2019/08/20 Python
Python 之 Json序列化嵌套类方式
2020/02/27 Python
python+openCV对视频进行截取的实现
2020/11/27 Python
使用OpenCV实现人脸图像卡通化的示例代码
2021/01/15 Python
HTML5本地存储之Database Storage应用介绍
2013/01/06 HTML / CSS
大学生年度自我鉴定
2013/10/31 职场文书
实习会计求职自荐信范文
2014/03/10 职场文书
2014年汽车销售工作总结
2014/12/01 职场文书
在职证明范本
2015/06/15 职场文书
解决Golang中goroutine执行速度的问题
2021/05/02 Golang
Redis性能监控的实现
2021/07/09 Redis