python类变量实例变量以及类和实例属性的查找顺序
2019-01-25 本文已影响0人
米斯特_李
1、类变量和实例变量

类变量可以通过类来调用,也可以通过实例来找到,但是其他地方修改了类变量之后,再通过实例找到类变量的值会发生变化:

如果通过实例来修改a的值之后,类里的a变量是没有变化的:

这样就会引出一个关于类和实例属性的查找顺序问题
2、类和实例属性的查找顺序
首先在实例a中如果有a.a的变量定义,就从实例中获取,如果没有就从类里找a变量,如果依然找不到就报错,但对于类来说,找的是类里的a变量,顺序往上找。
关于查找顺序再举个例子:

这里输出的是2,也就是说查找到的B这类的属性a=2

如果B类中没有定义a属性,找到的结果是1,也就是说查找到的是A类中的属性,由此我们得出结论关于python中类的继承,查找顺序是"深度查找",那么查找顺序就是B>A>D>C。

如果是这种继承关系呢,我在C中重写了A中的方法,我在D中恰好要用我C中重写的方法,如果按照之前所说的深度查询,那么我岂不是用不了C中重写的方法了?
接下来我们测试一下看看如果B中没有定义a,那么输出结果是什么呢?

what?输出结果和我们预想的不一致啊!!下面解释下:
如果是这种菱形的继承关系:貌似又变成了"广度查询"?? 答案:是的,这是因为python在查找类和实例属性的时候是有一个算法的,c3算法(有兴趣的同学可以研究一下这个算法)。
我们可以用__mro__来非常直观的查看调用顺序:


最后的object,python3中所有自定义的class都默认是继承object,即使没有定义,也是默认继承object。
了解了python类的继承关系,更有助于我们排错。