继承的实现原理

了解实现原理之前,我们先来了解一下 经典类 和 新式类。

 

一、经典类 和 新式类

经典类和新式类的区分是在Python2中才有的,在Python3 中所有的类都是新式类。

在Python2中:

经典类:没有继承object的类,以及它的子类都称为经典类。

class Foo: # 没有继承object,是经典类
    pass

class Bar(Foo):
    pass

 

新式类:继承object类,以及它的子类都称为新式类。

class Foo(object): # 继承了object类,是新式类
    pass

class Bar(Foo):
    pass

 

可以通过 __bases__ 查看是否继承了object类:

class P1:
    pass

class P2(object):
    pass

print(P1.__bases__)  # P1没有继承object类,输出为:()
print(P2.__bases__)  # P2继承了object类,输出为:(<class 'object'>,)

 

在Python3中:

没有经典类和新式类之分,只有新式类。

一个类没有继承object类,默认就继承了object类。

class Foo:
    pass

print(Foo.__bases__)  # 输出为:(<class 'object'>,)

 

 

二、继承实现原理

以上我们知道有经典类和新式类之分了之后,我们现在来看继承的实现原理,因为经典类和新式类的实现原理是不一样的。

 

Java和C#中子类只能继承一个类,而Python中子类可以同时继承多个父类,如果继承了多个父类,那么属性查找方式有两种,分别是:深度优先 和 广度优先。

 

1.当类是经典类时,多继承情况下,在要查找属性不存在时,会按照深度优先的方式查下去:

 

2.当类是新式类时,多继承情况下,在要查找属性不存在时,会按照广度优先的方式查下去:

 

来看实例代码:

# 示例代码
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()

运行结果为:from D

 

此实例代码的继承关系图如下:

经典类继承关系如下:

经典类继承顺序为:F->D->B->A->E->C

 

新式类继承关系如下:

新式类继承顺序:F->D->B->E->C->A

 

另外我们还以通过一个方法查看继承顺序,但只有新式类才有,经典类没有。

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'>)

 

 

版权声明:
作者:admin
链接:https://www.chenxie.net/archives/1845.html
来源:蜀小陈
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>