day20

一、继承

类的继承

  • 面向对象三要素之一,继承Inheritance

  • class Cat(Animal)这种形式就是从父类继承,继承可以让子类从父类获取特征(属性和方法)

  • 在面向对象的世界中,从父类继承,就可以直接拥有父类的属性和方法,这样可以减少代码,多复用,子类可以定义自己的属性和方法

    1、查看继承的特殊属性和方法

  • base : 类的基类

  • based : 类的基类元组

  • mro : 显示方法查找顺序,基类的元组

  • __mro()__方法 : 显示方法查找顺序,基类的元组

  • subclasses() : 类的子类列表

2、继承中的查找顺序

  • 从父类继承,自己没有的就可以到父类中找
  • 私有的都是不可以访问的,但是本质上依然是改了名称放在这个属性所在类的__dict_-中
  • 继承时,公有的,子类和实例都可以随意访问,私有成员被隐藏了,子类和实例不可直接访问
  • 当私有变量所在的类内的方法中可以访问这个私有变量
  • 属性查找属性:实例的dict--》类的dict--》父类dict

二、派生

​ 派生:子类定义自己新的属性,如果与父类同名,以子类自己的为准

在子类派生出的新方法中重用父类的功能:

方式一:指名道姓地调用(与继承没有什么关系)

方式二:super()调用(严格依赖于继承)

super ( ) 的返回值是一个特殊的对象,该对象专门用来调用父类中的属性,super()会严格按照mro列表从当前查找到的位置继续往后查找

经典类和新式类:

1、新式类: 继承object的类,以及该类的子类,都是新式类

在python3中,如果一个类没有指定继承的父类,默认就继承object,所以说python3中所有的类都是新式类

2、经典类(只有在python2才区分经典类与新式类):没有继承object的类,以及该类的子类,都是经典类

在多继承背景下的属性查找:

属性查找
obj.x
1、先从obj.dict
2、对象的类.dict
3、父类.dict

如果继承关系为非菱形结构,则会按照先找B这一条分支,然后再找C这一条分支,最后找D这一条分支的顺序直到找到我们想要的属性
如果继承关系为菱形结构,那么属性的查找方式有两种,分别是:深度优先和广度优先
print(F.mro) # F.mro() #只有新式类才有这个属性可以查看线性列表,查看属性查找顺序,经典类没有这个属性

菱形继承问题

在Python中子类可以同时继承多个父类,如A(B,C,D)

  • 如果继承关系为非菱形结构,则会按照先找B这一条分支,然后再找C这条分支,最后找D这条分支的顺序直到找到我们想要的属性
  • 如果继承关系为菱形结构,即子类的父类最后继承了同一个类,那么属性的查找方式有两种

经典类(了解)

一条路走到黑,深度优先

img

查找顺序:A -> B -> E -> G -> C -> F -> D

新式类

不找到各类最后继承的同一个类,直接去找下一个父类,广度优先

img

查找顺序:A -> B -> E -> C -> F -> D -> G

mro方法

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

print(A.__mro__)  # 在此用python3运行,广度优先
(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>)
for i in A.__mro__:
    print(i)
<class '__main__.A'>
<class '__main__.B'>
<class '__main__.E'>
<class '__main__.C'>
<class '__main__.F'>
<class '__main__.D'>
<class '__main__.G'>
<class 'object'>
原文地址:https://www.cnblogs.com/xwjhyy/p/11648031.html