多继承以及MRO顺序
class A:
def test(self):
print("A --- test方法") def demo(self):
print("A --- demo方法") class B:
def test(self):
print("B --- test方法") def demo(self):
print("B --- demo方法") class C(A,B):
pass c = C()
print(dir(c)) #dir()显示该类中所有的方法和属性
c.test()
c.demo()
print(C.__mro__) #向上查询顺序
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'demo', 'test']
A --- test方法
A --- demo方法
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
单个调用父类的方法:
# coding=utf-8
print("******多继承使用类名.__init__ 发生的状态******")
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, '男')
print('姓名:', gs.name)
print('年龄:', gs.age)
print('性别:', gs.gender)
print("******多继承使用类名.__init__ 发生的状态******\n\n")
结果:
******多继承使用类名.__init__ 发生的状态******
Grandson的init开始被调用
Son1的init开始被调用
parent的init开始被调用
parent的init结束被调用
Son1的init结束被调用
Son2的init开始被调用
parent的init开始被调用
parent的init结束被调用
Son2的init结束被调用
Grandson的init结束被调用
姓名: grandson
年龄: 12
性别: 男
******多继承使用类名.__init__ 发生的状态******
父类会被多次调用,浪费大量的资源
MRO和super()用法:
print("******多继承使用super().__init__ 发生的状态******")
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根据C3算法,每个类只调用一遍
# super(Grandson, self).__init__(name, age, gender) Grandson可以换成Son1或者其他,即 可以跳到指定的位置向上查询
super().__init__(name, age, gender) # 默认从Grandson开始查找MRO向上顺序
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().__init__ 发生的状态******
(<class '__main__.Grandson'>, <class '__main__.Son1'>, <class '__main__.Son2'>, <class '__main__.Parent'>, <class 'object'>)
Grandson的init开始被调用
Son1的init开始被调用
Son2的init开始被调用
parent的init开始被调用
parent的init结束被调用
Son2的init结束被调用
Son1的init结束被调用
Grandson的init结束被调用
姓名: grandson
年龄: 12
性别: 男
******多继承使用super().__init__ 发生的状态******
super总结:
super().__init__相对于类名.__init__,在单继承上用法基本无差
但在多继承上有区别,super方法能保证每个父类的方法只会执行一次,而使用类名的方法会导致方法被执行多次,具体看前面的输出结果
多继承时,使用super方法,对父类的传参数,应该是由于python中super的算法导致的原因,必须把参数全部传递,否则会报错
单继承时,使用super方法,则不能全部传递,只能传父类方法所需的参数,否则会报错
多继承时,相对于使用类名.__init__方法,要把每个父类全部写一遍, 而使用super方法,只需写一句话便执行了全部父类的方法,这也是为何多继承需要全部传参的一个原因
多继承以及MRO顺序的更多相关文章
- 08私有化、MRO顺序
一. 私有化 1)xx: 公有变量 2)_x: 单前置下划线,私有化属性或方法,from somemodule import *禁止导入,类对象和子类可以访问 3)__xx:双前置下划线,避免与子类中 ...
- 面向对象:静态属性,静态方法,组合,继承,衍生,继承之mro线性顺序列表,面向对象综合实例
1.静态属性(附有装饰器) class Room: def __init__(self,name,owner,width,length,height): self.name=name self.own ...
- Python多继承之MRO算法
MRO即Method Resolution Order 方法解析顺序,它的提出主要是为了解决Python中多继承时,当父类存在同名函数时,二义性的问题 下面先看一个例子: import inspe ...
- python基础之面向对象的多继承以及MRO算法
内容梗概: 1. python多继承 2. python经典类的MRO 3. python新式类的MRO C3算法 1.python多继承 class Shen: def fly(self): pri ...
- 第二十天- 多继承 经典MRO 新式MRO super()
# 多继承:# 在继承关系中.⼦类自动拥有⽗类中除私有属性外其他所有内容.python⽀持多继承.子类可拥有多⽗类. class ShenXian: # 神仙 def fei(self): print ...
- python学习笔记:第20天 多继承、MRO C3算法
目录 一.多继承 二.旧式类的MRO 三.新式类的MRO 四.super 一.多继承 之前已经学习过了继承,当出现了x是⼀种y的的时候,就可以使⽤继承关系,即"is-a" 关系.在 ...
- python的多继承C3(mro)算法
多继承的继承顺序按照C3算法进行顺序继承 例一 按照深度A类从左往右有三条可继承的"路" 先按照深度优先的算法,将每一路的每一个节点加到列表中 B = [B,D,F,H] C = ...
- PythonI/O进阶学习笔记_3.2面向对象编程_python的继承(多继承/super/MRO/抽象基类/mixin模式)
前言: 本篇相关内容分为3篇多态.继承.封装,这篇为第二篇 继承. 本篇内容围绕 python基础教程这段: 在面向对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法.使 ...
- Python的多继承问题-MRO和C3算法
大部分内容转载自C3 线性化算法与 MRO 理解Python中的多继承 Python 中的方法解析顺序(Method Resolution Order, MRO)定义了多继承存在时 Python 解释 ...
随机推荐
- java junit4-JUnit测试报 No socket available 错误
问题描述 JUnit测试报 No socket available 错误 Eclipse进行JUnit测试时,总弹出 No socket available 窗口,导致测试不能进行. 解决方案一: 打 ...
- [转帖]TPC-C解析系列03_TPC-C基准测试之SQL优化
TPC-C解析系列03_TPC-C基准测试之SQL优化 http://www.itpub.net/2019/10/08/3330/ TPC-C是一个非常严苛的基准测试模型,考验的是一个完备的关系数据库 ...
- find_element_by_xpath()的几种方法
Xpath (XML Path Language),是W3C定义的用来在XML文档中选择节点的语言一:从根目录/开始有点像Linux的文件查看,/代表根目录,一级一级的查找,直接子节点,相当于css_ ...
- golang开发:(一)开发环境搭建vagrant+VirtualBox
开发环境介绍 不管何种开发语言,目前用的比较多的开发环境基本就是Vagrant+VirtualBox搭建的虚拟开发环境,这种开发环境的好处就是一次搭建处处可用,各个平台和系统都可以使用.开发团队中,可 ...
- ES6语法基本使用
什么是ES6? ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了.Mozilla公司将在这个标准的基础上,推出JavaScript 2. ...
- Liar CodeForces - 822E (dp,后缀数组)
大意: 给定串$s,t$, 给定整数$x$, 求判断$t$是否能划分为至多$x$段, 使这些段在$s$中按顺序,不交叉的出现. 设$dp_{i,j}$表示$s$匹配到$i$位, 划分了$j$段, 匹配 ...
- 使用Docker发布Asp.Net Core程序到Linux
CentOS安装Docker 按照docker官方文档来,如果有之前安装过旧版,先卸载旧版,没有的话,可跳过. sudo yum remove docker \ docker-client \ doc ...
- Dijkstra+Heap模板
普通Dijkstra: void DijkstraPath(int v0,int vis[],int dist[],int path[]) { int onePath[maxn]; int d; in ...
- 【日语】日语单词N3_N4_N5
日语单词N3_N4_N5 单 词 讲 解 あ行单词 ああ:0[副]那样.那种 例句:ああ言うことはしないほうがいい.那样的事情最好不做. 電車の窓からごみを棄てているああ言うことはしないほうがいい. ...
- 在iframe内页触发顶层页面body的blur事件
//在iframe内页触发顶层页面body的blur事件. if (window != top) { $(document.body).click(function () { $(top.docume ...