Python之旅——带着决心出发(第9步)

一、基础篇

10. 类继承属性搜索规则

规则:

    根据类的继承关系树,自底向上,自左向右搜索,直到找到第一个属性为止。(如果未找到,抛出异常)

Python之旅——带着决心出发(第9步)

图片来自:《Learning Python 5th Edition》一书Figure 26-1

例如:C1继承C2和C3两个类,那么C1类的对象I1对某个属性的访问,搜索路径

      I1.name : I1;
      I1.x    : I1->C1;
      I1.y    : I1->C1;
      I1.z    : I1->C1->C2;
      I1.w    : I1->C1->C2->C3;


从Python的搜索路径来看:
①子类定义了与父类相同的属性,那么通过对象访问的方式,子类将覆盖父类的属性;

②存在多继承且各父类中存在相同的属性(图中的C2和C3的z)时,“左边”的父类将覆盖“右边”的父类。

代码举例:

class C2(object):
def __init__(self):
self.x = 10
self.z = 20

class C3(object):
def __init__(self):
self.w = 15
self.z = 25

class C1(C2, C3):
def __init__(self):
C3.__init__(self)
C2.__init__(self)
self.x = 12
self.y = 13
if __name__ == "__main__":
I1 = C1()
I1.m = 33
print("I1.m", I1.m)
print("I1.x", I1.x)
print("I1.y", I1.y)
print("I1.z", I1.z)
print("I1.w", I1.w)


输出结果:

I1.m 33
I1.x 12
I1.y 13
I1.z 20

I1.w 15


疑问:

1.如果将C3.__init__(self)和C2.__init__(self)两行语句交换,则输出结果:

I1.m 33
I1.x 12
I1.y 13
I1.z 25
I1.w 15

猜想:这两行语句决定了多继承中,父类中的“左”和“右”?该如何理解?

2.如果将C3.__init__(self)和C2.__init__(self)两行语句删除,将会报告如下错误:

AttributeError: 'C1' object has no attribute 'z'

猜想:这两行语句决定了子类是否继承父类中的属性?