继承的实现原理
了解实现原理之前,我们先来了解一下 经典类 和 新式类。
一、经典类 和 新式类
经典类和新式类的区分是在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'>)
共有 0 条评论