一、背景
最开始遇到这个特性的场景是这样的:
有两个基类,已经开发好基础的接口,示例如下:
class A:
def __init__(self):
pass
def func1(self):
pass
class B:
def __init__(self):
pass
def func2(self):
pass
然后对外的接口需要分别调用A中的func1和B中的func2,尝试的方式是:
class C(A, B):
def __init__(self):
super().__init__()
def run(self):
self.func1()
self.func2()
这样很简单完事。
上面的场景里涉及到一个知识点,多重继承。它的使用方式上最关键的点在于
class C(A, B):
def __init__(self):
super().__init__()
那这里的super的作用是什么?以及当一个类有多个继承关系的时候,是如何决定使用哪个类的方法的。
二、敲重点!
-
super()是一个内置类,其完整版应该是接收两个参数,第一个是type,第二个是type或者是一个object,第二个参数决定了MRO链,第一个参数决定MRO链中起始位置。super()这一内置类能动态地根据MRO链来初始化函数。而不用程序员手动去一个一个继承类去分别初始化。
-
上面说到的MRO是什么?英文全称为Method Resolution Order,翻译中文为
方法解析顺序
。在python里,是支持继承其他类的方法和数据,而MRO就是python子类如何从父类中优先找继承的顺序。
在很多简单的类继承的例子中,这种继承的先后顺序显而易见
class A:
def say(self):
print('my name is A')
class B:
def say(self):
print('my name is B')
class C(A):
pass
class M(C, B):
pass
m = M()
## M -> C -> A -> B
m.say()
## 'my name is A'
下面相对费解的继承关系是这样
class A:
def say(self):
print('my name is A')
class B(A):
def say(self):
print('my name is B')
class C(A):
pass
class M(C, B):
pass
m = M()
## M -> C -> B -> A
m.say()
## 'my name is B'
在python中的MRO里用到的算法为C3 linear,满足以下三个特性:
a. 扩展后的一致性
b. 局部优先顺序
c. 单调性
三、使用注意
- 继承结构要清晰明了,不要写非常复杂的继承污染代码;
- 对于不确定的继承关系,可以使用.mro()看看继承顺序;
网友评论