python基础——继承实现的原理

1 继承顺序

class A(object):
def test(self):
print('from A') class B(A):
def test(self):
print('from B') class C(A):
def test(self):
print('from C') class D(B):
def test(self):
print('from D') class E(C):
def test(self):
print('from E') class F(D,E):
# def test(self):
# print('from F')
pass
f1=F()
f1.test()
print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性 #新式类继承顺序:F->D->B->E->C->A
#经典类继承顺序:F->D->B->A->E->C
#python3中统一都是新式类
#pyhon2中才分新式类与经典类

  

2 继承原理(python如何实现的继承)

python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如

>>> F.mro() #等同于F.__mro__
[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>,
<class 'object'>]

为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止 

合并所有父类的MRO列表并遵循如下三条准则:
1.子类会先于父类被检查
2.多个父类会根据它们在列表中的顺序被检查
3.如果对下一个类存在两个合法的选择,选择第一个父类

3 子类中调用父类方法(super()方法)

子类继承了父类的方法,然后想进行修改,注意了是基于原有的基础上修改,那么就需要在子类中调用父类的方法

方法一  父类名.父类方法()

class People:
def __init__(self,name,sex,age):
self.name=name
self.sex=sex
self.age=age
def walk(self):
print('%s is walking'%self.name) class Chinese(People):
country='China'
def __init__(self,name,sex,age,language='Chinses'):
People.__init__(self,name,sex,age)
self.language=language
def walk(self,x):
pass c=Chinese('xiaojing','male',20)
print(c.name,c.sex,c.age,c.language)

方法二 super()方法

class People:
def __init__(self,name,sex,age):
self.name=name
self.age=age
self.sex=sex
def walk(self):
print('%s is walking'%self.name)
class Chinese(People):
country='China'
def __init__(self,name,sex,age,language='Chinese'):
super().__init__(name,sex,age) #super() 绑定 调用父类方法
self.language=language
def walk(self,x):
super().walk()
print("---->子类的x",x)
c=Chinese('EGG','male','20')
c.walk(123)

不用super引发的惨案

#每个类中都继承了且重写了父类的方法
class A:
def __init__(self):
print('A的构造方法')
class B(A):
def __init__(self):
print('B的构造方法')
A.__init__(self) class C(A):
def __init__(self):
print('C的构造方法')
A.__init__(self) class D(B,C):
def __init__(self):
print('D的构造方法')
B.__init__(self)
C.__init__(self) pass
f1=D() print(D.__mro__) #python2中没有这个属性

当你使用super()函数时,Python会在MRO列表上继续搜索下一个类。只要每个重定义的方法统一使用super()并只调用它一次,那么控制流最终会遍历完整个MRO列表,每个方法也只会被调用一次(注意注意注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表

#每个类中都继承了且重写了父类的方法
class A:
def __init__(self):
print('A的构造方法')
class B(A):
def __init__(self):
print('B的构造方法')
super(B,self).__init__() class C(A):
def __init__(self):
print('C的构造方法')
super(C,self).__init__() class D(B,C):
def __init__(self):
print('D的构造方法')
super(D,self).__init__() f1=D() print(D.__mro__) #python2中没有这个属性

python基础——继承实现的原理的更多相关文章

  1. python基础——继承和多态

    python基础——继承和多态 在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类.父类或超类 ...

  2. python基础——继承与派生、组合

    python基础--继承与派生 1 什么是继承: 继承是一种创建新的类的方式,在python中,新建的类可以继承自一个或者多个父类,原始类成为基类或超累,新建的类成为派生类或子类 1.1 继承分为:单 ...

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

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

  4. python基础===继承

    编写类时,并非总是要从空白开始.如果你要编写的类是另一个现成类的特殊版本,可使用继承.一个类继承另一个类时,它将自动获得另一个类的所有属性和方法:原有的类称为父类,而新类称为子类.子类继承了其父类的所 ...

  5. Python基础-继承与派生

    一.继承 继承是一种创建新的类的方式,在python中,新建的类可以继承自一个或者多个父类,原始类称为基类或超类,新建的类称为派生类或子类. python中类的继承分为:单继承和多继承 class P ...

  6. python基础===继承和多继承

    继承 class A: def spam(self): print("A.SPAM") def add(self, x,y): return x+y class B(A): def ...

  7. Python基础(17)_面向对象程序设计(抽象类、继承原理、封装、多态,绑定方法)

    一.抽象类 抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化 1.在python中实现抽象类 import abc #利用abc模块实现抽象类 class All_file(metacl ...

  8. Python基础之继承与派生

    一.什么是继承: 继承是一种创建新的类的方式,新建的类可以继承一个或过个父类,原始类成为基类或超类,新建的类则称为派生类 或子类. 其中,继承又分为:单继承和多继承. class parent_cla ...

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

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

随机推荐

  1. node 自动重启 nodemon

    最近在玩node,可是每次修改完js,总要重启下服务,还要杀掉端口,感觉可麻烦了,最近发现nodemon这个东西很好,直接解决了我的烦恼. npm install -g nodemon 以后直接启动n ...

  2. go语言defer panic recover用法总结

    defer defer是go提供的一种资源处理的方式.defer的用法遵循3个原则 在defer表达式被运算的同时,defer函数的参数也会被运算.如下defer的表达式println运算的同时,其入 ...

  3. 20165230 2017-2018-2 《Java程序设计》第2周学习总结

    20165230 2017-2018-2 <Java程序设计>第2周学习总结 教材学习内容总结 本周学习了JAVA中的数据类型.数组.运算符.表达式和语句,与C语言很类似,二者也有区别. ...

  4. Android 零散知识点整理

    Android 零散知识点整理 为什么Android的更新试图操作必须在主线程中进行? 这是因为Android系统中的视图组件并不是线程安全的.通常应该让主线程负责创建.显示和更新UI,启动子线程,停 ...

  5. 1-4 criteria用法大全

    Criteria的完整用法 QBE (Query By Example) Criteria cri = session.createCriteria(Student.class); cri.add(E ...

  6. springMVC的异常处理

    1. 异常 什么是异常: 在程序中预期会出现,但是却无法处理的问题,叫做异常 异常处理原则: 延迟处理 先记着...,后续补充

  7. 发布利用 Qt Assistant来做帮助系统的程序遇到的问题

    最近,一直在做反演初始模型可视化建模的软件 model Constraint,最后的步骤就是利用 Qt Assistant为自己的程序制作帮助系统. 1.<Qt Creator快速入门>和 ...

  8. drbd(二):配置和使用

    本文目录:1.drbd配置文件2.创建metadata区并计算metadata区的大小3.启动drbd4.实现drbd主从同步5.数据同步和主从角色切换6.drbd脑裂后的解决办法7.drbd多卷组配 ...

  9. 201621123040《Java程序设计》第2周学习总结

    1.本周学习总结 关键词:Java中的字符串与数组 c语言基本语法的迁移 相关总结:在一周的学习过程中,我自主学习Java的基本语法,前期的相关语法与c语言的基本语法相近,也算是做到了很好的回顾:在郑 ...

  10. C程序设计-----第0次作业

    C程序设计-----第0次作业- 1.翻阅邹欣老师的关于师生关系博客,并回答下列问题,每个问题的答案不少于500字:(50分)- 1)最理想的师生关系是健身教练和学员的关系,在这种师生关系中你期望获得 ...