新式类和经典类的继承原理,super的用法
day29
继承顺序
-
Python的类可以继承多个类,Java和C#中则只能继承一个类
-
Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先
当类是经典类时,多继承情况下,会按照深度优先方式查找
当类是新式类时,多继承情况下,会按照广度优先方式查找
在Python3中所有的都是新式类
在Python2中才有新式类和经典的区分,写法上的区分:如果当前类或父类继承了object类,那么该类便是新式类,否则便是经典类。
例子1:
继承关系如下图:
查找顺序是:
F-->D-->B-->X-->E-->C-->A-->object
例子2:
继承关系如下图:
查找顺序是:
F-->D-->B-->X-->E-->C--Y-->object
例子3:
继承关系如下图:
查找顺序是:
H-->E-->B-->F-->C-->G-->D-->A-->object
Python2经典类继承顺序:深度优先
例子:
继承关系如下:
查找顺序是:
F-->D-->B-->X-->A-->E-->C
继承原理(python如何实现的继承)
python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如:
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'>]
为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,他实际上就是合并所有父类的MRO列表,并遵循如下三条准则:
-
子类会先于父类被检查
-
多了父类会根据他们在列表中的顺序被检查
-
如果对下一个类存在两个合法的选择,选择第一个父类
新式类:
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 print(F.__mro__) # 只有新式才有这个属性可以查看线性列表,经典类没有这个属性 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'>) [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
super的用法
super在python2中的用法:
super(自己的类名,self).父类的函数名字
super只能用于新式类
在Python3中:
class People: def __init__(self, name, sex, age): self.name = name self.sex = self self.age = age def walk(self): print("%s is walking.." % (self.name)) class Chinese(People): country = "China" def __init__(self, name, sex, age, language="Chinese"): # People.__init__(self, name, sex, age) # 之前的写法 super().__init__(name, sex, age) # super用法,调的父类的绑定办法,所以不需要传self # super(Chinese,self).__init__(name, sex.age) # python2的写法,并且父类必须是新式类People要继承object,People(object) self.langueage = language c = Chinese("alex", "male", 18) c.walk()
输出:
alex is walking..
共有 0 条评论