1. 我们先想一下在python中如果子类方法中想执行父类的方法,有什么方式?大概有三种:

  • Parent.__init__(self, name)     # 通过父类的名字,指定调用父类的方法
  • super().__init__(name, *args, **kwargs)  # 通过super()自动调用父类的方法
  • super(Son2, self).__init__(name, *args, **kwargs)  # 通过super()并且传入一个类型名字,执行某个类的方法,这样就跳开super默认的执行顺序

2. 下面举例说明每一种方式

class Parent(object):
def __init__(self, name):
print('parent的init开始被调用')
self.name = name
print('parent的init结束被调用') class Son1(Parent):
def __init__(self, name, age):
print('Son1的init开始被调用')
self.age = age
Parent.__init__(self, name)
print('Son1的init结束被调用') class Son2(Parent):
def __init__(self, name, gender):
print('Son2的init开始被调用')
self.gender = gender
Parent.__init__(self, name)
print('Son2的init结束被调用') class Grandson(Son1, Son2):
def __init__(self, name, age, gender):
print('Grandson的init开始被调用')
Son1.__init__(self, name, age) # 单独调用父类的初始化方法
Son2.__init__(self, name, gender)
print('Grandson的init结束被调用') gs = Grandson('grandson', 12, '男')

单独调用父类的方法

在例子中,son1 son2 继承了parent类,Grandson 继承了son1 son2,并且在son1 son2 的构造方法中分别调用了父类的构造方法,在Grandson的构造方法中调用了 son1 son2 的构造方法。

运行结果:

父类parent的构造方法被执行2次。这就是直接使用父类名去调用的稍微不好的地方。

randson的init开始被调用
Son1的init开始被调用
parent的init开始被调用
parent的init结束被调用
Son1的init结束被调用
Son2的init开始被调用
parent的init开始被调用
parent的init结束被调用
Son2的init结束被调用
Grandson的init结束被调用
姓名: grandson
年龄: 12
性别: 男

鉴于上面调用的不足之处,有了super()方式的调用。

class Parent(object):
def __init__(self, name, *args, **kwargs): # 为避免多继承报错,使用不定长参数,接受参数
print('parent的init开始被调用')
self.name = name
print('parent的init结束被调用') class Son1(Parent):
def __init__(self, name, age, *args, **kwargs): # 为避免多继承报错,使用不定长参数,接受参数
print('Son1的init开始被调用')
self.age = age
super().__init__(name, *args, **kwargs) # 为避免多继承报错,使用不定长参数,接受参数
print('Son1的init结束被调用') class Son2(Parent):
def __init__(self, name, gender, *args, **kwargs): # 为避免多继承报错,使用不定长参数,接受参数
print('Son2的init开始被调用')
self.gender = gender
super().__init__(name, *args, **kwargs) # 为避免多继承报错,使用不定长参数,接受参数
print('Son2的init结束被调用') class Grandson(Son1, Son2):
def __init__(self, name, age, gender):
print('Grandson的init开始被调用')
# 多继承时,相对于使用类名.__init__方法,要把每个父类全部写一遍
# 而super只用一句话,执行了全部父类的方法,这也是为何多继承需要全部传参的一个原因
# super(Grandson, self).__init__(name, age, gender)
super().__init__(name, age, gender)
print('Grandson的init结束被调用') print(Grandson.__mro__) gs = Grandson('grandson', 12, '男')
print('姓名:', gs.name)
print('年龄:', gs.age)
print('性别:', gs.gender)
print("******多继承使用super().__init__ 发生的状态******\n\n")

super调用

首先,如果一个类继承多各类,比如本例中的 Grandson, 那么该类有一个__mro__的属性,该属性的值表示类的继承顺序。

(<class '__main__.Grandson'>, <class '__main__.Son1'>, <class '__main__.Son2'>, <class '__main__.Parent'>, <class 'object'>)

那么如果使用super调用父类方法时,就依此顺序执行它的父类的方法。

如图描述

这样执行下来,parent类中的构造方法,就被执行一次。

执行顺序用途表示如下图

而在super()函数中传入类型参数时,执行这个指定类的父类的方法.

子类中执行父类的方法(引出super()与mro列表)的更多相关文章

  1. 在子类中调用父类的方法super

    1.没有super之前,在子类里面需要父类里面的逻辑,但是我们是通过派生(自己定义了一个init,增加了一条line) class vehichle:#定义一个交通工具的类 Country=" ...

  2. Python 在子类中调用父类方法详解(单继承、多层继承、多重继承)

    Python 在子类中调用父类方法详解(单继承.多层继承.多重继承)   by:授客 QQ:1033553122   测试环境: win7 64位 Python版本:Python 3.3.5 代码实践 ...

  3. python基础----继承与派生、组合、接口与归一化设计、抽象类、子类中调用父类方法

    一.什么是继承                                                                          继承是一种创建新的类的方式,在pyth ...

  4. python基础之类的继承与派生、组合、接口与归一化设计、抽象类、子类中调用父类方法

    一.什么是继承 继承是一种创建新的类的方式,新建的类可以继承自一个或者多个父类,原始类称为基类或超类,新建的类称为派生类或子类. 派生:子类继承了父类的属性,然后衍生出自己新的属性,如果子类衍生出的新 ...

  5. python学习-65 继承2-子类中调用父类的方法

    子类中调用父类的方法 1.子类继承了父类的方法,然后想进行修改,那么就需要在子类中调用父类的方法. 2.方法一:父类名 class School: Country = 'china' def __in ...

  6. Python之面向对象的组合、多态、菱形问题、子类中重用父类的两种方式

    一.组合 ''' 1.什么是组合 组合就是一个类的对象具备某一个属性,该属性的值是指向另外一个类的对象 2.为何用组合 组合也是用来解决类与类直接代码冗余问题的 3.如何用组合 ''' # 继承减少代 ...

  7. 重写UITableViewCell子类中属性的setter方法来实现隐藏或显示该cell中的某些控件

    重写UITableViewCell子类中属性的setter方法来实现隐藏或显示该cell中的某些控件 为什么会需要这样子的一种方法来实现隐藏或者显示一个cell中的某些控件呢? 其实,隐藏cell中某 ...

  8. super之mro列表牵引出c3算法

    目录 一:super的使用 二:super之mro列表牵引出c3算法 三:mro列表总结使用 一:super的使用 class Person(object): def __init__(self, n ...

  9. c++与java中子类中调用父类成员的方法

    java中: import java.util.Scanner; public class ClassTest{ public static void main(String args[]){ chi ...

随机推荐

  1. 命令行发送SMTP协议邮件(163邮箱)

    这里我们用163邮箱为例子,借助命令行发送smtp邮件 1.连接服务器 在终端上输入:telnet smtp.163.com 25 回车,然后就连接了服务器的25端口,成功会输出 220 163.co ...

  2. zepto学习(三)之详解

    zepto Zepto就是jQuery的移动端版本, 可以看做是一个轻量级的jQuery github地址: https://github.com/madrobby/zepto 官方地址: http: ...

  3. springboot有第三方jar打包成jar

    <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven ...

  4. 判断Actiivty是否已经被销毁

    一般会遇到这样的情况:在一个Activity中启动一个异步任务,异步任务中需要返回值,然后被Activity使用,但是当异步任务还未结束时,按下home键,如果这个时候系统内存比较紧张,这个Activ ...

  5. 阿里十年架构师告诉你Spring Boot与Spring Cloud是什么关系

    SpringBoot先于Spring Cloud问世.SpringBoot相当于脚手架,借助他可以快速搭建房子,它本身不具备任何功能属性,值是普通房间,没有其他任何功能. 什么是Spring Boot ...

  6. 【loj#2524】【bzoj5303】 [Haoi2018]反色游戏(圆方树)

    题目传送门:loj bzoj 题意中的游戏方案可以转化为一个异或方程组的解,将边作为变量,点作为方程,因此若方程有解,方程的解的方案数就是2的自由元个数次方.我们观察一下方程,就可以发现自由元数量=边 ...

  7. MPU6050应用

    @2019-08-07 [小记] MPU6050开发 -- 基本概念简介 MPU6050原理详解及实例应用 详解卡尔曼滤波原理 卡尔曼算法精讲与C++实现

  8. 判断一个python字符串中是否包含中文字符

    #在python中一个汉字算一个字符,一个英文字母算一个字符 #用 ord() 函数判断单个字符的unicode编码是否大于255即可. def is_contain_chinese(check_st ...

  9. troubshooting-sqoop 导出 TiDB表数据报com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

    2019-11-22 17:15:27,705 FATAL [IPC Server handler 13 on 44844] org.apache.hadoop.mapred.TaskAttemptL ...

  10. GET与POST方法和用curl命令执行

    1.超文本传输协议 超文本传输协议(HTTP)的设计目的是保证客户机与服务器之间的通信,web 浏览器可能是客户端,而计算机上的网络应用程序也可能作为服务器端. HTTP的工作方式是客户机与服务器之间 ...