首页 » 编程 » Python » 正文

新式类和经典类的继承原理,super的用法

day29

继承顺序

  1. Python的类可以继承多个类,Java和C#中则只能继承一个类

  2. Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先

001.png

当类是经典类时,多继承情况下,会按照深度优先方式查找

当类是新式类时,多继承情况下,会按照广度优先方式查找


在Python3中所有的都是新式类

在Python2中才有新式类和经典的区分,写法上的区分:如果当前类或父类继承了object类,那么该类便是新式类,否则便是经典类。

002.png


例子1:

继承关系如下图:

02.png

查找顺序是:

F–>D–>B–>X–>E–>C–>A–>object


例子2:

继承关系如下图:

03.png

查找顺序是:

F–>D–>B–>X–>E–>C–Y–>object


例子3:

继承关系如下图:

04.png

查找顺序是:

H–>E–>B–>F–>C–>G–>D–>A–>object


Python2经典类继承顺序:深度优先

例子:

继承关系如下:

05.png


查找顺序是:

F–>D–>B–>X–>A–>E–>C


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

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

print(F.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列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,他实际上就是合并所有父类的MRO列表,并遵循如下三条准则:

  1. 子类会先于父类被检查

  2. 多了父类会根据他们在列表中的顺序被检查

  3. 如果对下一个类存在两个合法的选择,选择第一个父类


新式类:

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
    
print(F.__mro__)  # 只有新式才有这个属性可以查看线性列表,经典类没有这个属性
print(F.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'>)

[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]


super的用法

super在python2中的用法:

super(自己的类名,self).父类的函数名字

super只能用于新式类


在Python3中:

class People:
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = self
        self.age = age
    def walk(self):
        print("%s is walking.." % (self.name))

class Chinese(People):
    country = "China"
    def __init__(self, name, sex, age, language="Chinese"): 
        # People.__init__(self, name, sex, age)  # 之前的写法
        super().__init__(name, sex, age)  # super用法,调的父类的绑定办法,所以不需要传self
        # super(Chinese,self).__init__(name, sex.age)  # python2的写法,并且父类必须是新式类People要继承object,People(object)
        self.langueage = language

c = Chinese("alex", "male", 18)
c.walk()

输出:

alex is walking..




发表评论