python面向对象–继承(MRO)
最近觉得py的基础还是有必要再看一下的。
python的多继承的属性继承搜索
Python在处理多继承时同名函数,如果处理呢?
Ex
|
|
在经典类中输出如下:output
|
|
在新类中输出如下:output
|
|
很明显的是,在老式的py类(py2.3以前的版本或者在py2.3+之后的版本中没有显示声明)中,依据的是从左到右,深度优先
的规则.然而在新式类中,采用的是另外一套规则.所以在代码中混合新式类和旧式类,在MRO中会有不用的表现
使用类的__mro__
属性可以得到一个可读的查找顺序表
mro即method resolution order,主要用于在多继承时判断调的属性的路径(来自于哪个类)。python在2.3中使用的是C3算法.
python 需要对其进行线性化(C3 Linearization),将继承图关系线性化。通过线性化,再依次查找类方法,直至找到该方法为止。线性化算法是python多继承的核心部分。线性化过程中,必须满足两个性质:
单调性
一致性
直接父类的顺序通过用户来声明,父类线性化的顺序为从左到右。在进行线性化归并过程中,一致性主要保证类的局部优先级顺序,它定义了两个变量:
python多重继承
python在多重继承中的问题?
来看<
|
|
结果报错,输出如下:
|
|
why?
因为在SongBrid中,构造方法被重写.所以找不到属性了
解决方法:
- 1:调用未绑定的超类构造方法.
|
|
- 2:使用super函数(新式类才可以这么做)
|
|
super()类还是方法?
打印了以下super()
的类型,发现类型是
Super的缺陷
基类中的__init__
不会被显示调用,所以需要开发人员调用.
混用super和传统调用
|
|
output:
|
|
可以看到,当C实例调用A.__init__(self)
,因为super(A, self).init()将调用B的构造程序.
不同类型的参数
|
|
一种解决方式,就是给所有的init(self), 替换成init(self, args, *kw)
最佳实践
- 减少使用多继承
- super不能混用
- 检查MRO