一、前言

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)

夜深了,暂时会这么多就写这么多,有空研究c3原理(挖个坑先)

Python 关于super 的 用法和原理(挖坑)的更多相关文章

  1. 转 -- 详解python的super()的作用和原理

    原文地址 Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递. 今天我们介绍的主角是supe ...

  2. python的super深入了解(转)

    1.python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通方法和super方法 假设Base是基类 class Base(object): def __init__(s ...

  3. Python: 你不知道的 super

    https://segmentfault.com/a/1190000007426467 Python: 你不知道的 super 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我 ...

  4. Python下探究随机数的产生原理和算法

    资源下载 #本文PDF版下载 Python下探究随机数的产生原理和算法(或者单击我博客园右上角的github小标,找到lab102的W7目录下即可) #本文代码下载 几种随机数算法集合(和下文出现过的 ...

  5. python之super()函数

    python之super()函数 python的构造器奇特, 使用魔方. 构造器内对基类对象的初始化同样也很奇特, 奇特到没有半点优雅! 在构造器中使用super(class, instance)返回 ...

  6. 由Python的super()函数想到的

    python-super *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !im ...

  7. Python源代码剖析笔记3-Python运行原理初探

    Python源代码剖析笔记3-Python执行原理初探 本文简书地址:http://www.jianshu.com/p/03af86845c95 之前写了几篇源代码剖析笔记,然而慢慢觉得没有从一个宏观 ...

  8. MariaDB/MySQL备份和恢复(三):xtrabackup用法和原理详述

    本文目录: 1.安装xtrabackup 2.备份锁 3.xtrabackup备份原理说明 3.1 备份过程(backup阶段) 3.2 准备过程(preparing阶段) 3.3 恢复过程(copy ...

  9. python中super的理解(转)

    原文地址:https://www.zhihu.com/question/20040039 针对你的问题,答案是可以,并没有区别.但是这题下的回答我感觉都不够好. 要谈论 super,首先我们应该无视 ...

随机推荐

  1. python3 第二十一章 - 函数式编程之return函数和闭包

    我们来实现一个可变参数的求和.通常情况下,求和的函数是这样定义的: def calc_sum(*args): ax = 0 for n in args: ax = ax + n return ax 但 ...

  2. linux_快照和克隆

    什么是快照? 操作虚拟机时候,想保存当前状态为以后操作失误快速那时保存的系统状态,想当于对系统的版本管理,每个节点之间可以互相切换 什么是克隆? 可以选择快照和当前状态,可选择链接克隆和完整克隆 链接 ...

  3. Linux指令--cd,pwd

    本文参照博客做了修改和总结,感谢作者的分享.http://www.cnblogs.com/peida/archive/2012/10/24/2736501.html cd 命令可以说是Linux中最基 ...

  4. zabbix图形乱码

    毕竟是中文为主,特别是有些香项目最好以中文命名,容易区分,也方便识别 环境: centos7.3安装zabbix3.2 问题: 图文乱码问题 原理上只要找到对应的字符集,在修改配置文件 windows ...

  5. 珍爱生命,远离JS=>JS避坑记

    JavaScript避坑记 转载请注明源地址: http://www.cnblogs.com/funnyzpc/p/8407952.html 上图=> 有意思的漫画,不知大家看懂了没,这里我想说 ...

  6. [DeeplearningAI笔记]改善深层神经网络_优化算法2.6_2.9Momentum/RMSprop/Adam优化算法

    Optimization Algorithms优化算法 觉得有用的话,欢迎一起讨论相互学习~Follow Me 2.6 动量梯度下降法(Momentum) 另一种成本函数优化算法,优化速度一般快于标准 ...

  7. [TFRecord文件格式]基本介绍

    标准TensorFlow格式 TFRecords 觉得有用的话,欢迎一起讨论相互学习~Follow Me TFRecords可以允许你讲任意的数据转换为TensorFlow所支持的格式, 这种方法可以 ...

  8. php动态编译mysqli扩展

    在源PHP安装文件中进入注意是你下载的php源文件软件包cd ./php-5.5.4/ext/mysqli注意要先确保/server/php/bin/php-config存在/server/php/b ...

  9. ABP官方文档翻译 2.7 对象到对象的映射

    对象到对象的映射 介绍 IObjectMapper接口 AutoMapper集成 安装 创建映射 自动映射属性 自定义映射 MapTo扩展方法 单元测试 预定义映射 LocalizeableStrin ...

  10. (转)Elasticsearch 5 Ik+pinyin分词配置详解

    今天以这篇文章结束同城旅游网的面试,正好面试官也问到站内检索,可以尝试一下这篇文章介绍的方法.Elasticsearch 5 Ik+pinyin分词配置详解