python 在类的继承中,当前类中如果方法与基类(父类)的方法一样,会覆盖基类的方法。
classBase(object):defrun(self):print("Base start running~~")classDog(Base):defrun(self):print("Dog start running~~")if __name__ == "__main__":
Dog().run()#结果
Dog start running~~Process finished with exit code 0
上面代码代码中,基类Base 并没有执行,但是有些时候,定义基类就是把共同的代码写在一起,在调用当前方法是,我们基类中已经实现的公共部分。
类的继承
经典类(classic class) 基类名.方法名(self, *args, **kwargs), python版本低于2.2
新式类(new-style class) super(当前类名, self).方法名(*args, **kwargs), python 版本大于2.2
1 classBase(object):2 defrun(self):3 print("Now start running~~")4
5 classDog(Base):6 defrun(self):7 Base.run(self) # 经典类继承8 print("Dog start running~~")9
10 if __name__ == "__main__":11 Dog().run()12
13 #结果
14 Now start running~~
15 Dog start running~~
16
17 Process finished with exit code 0
当使用经典类继承时,Dog->Base->object 这种简单的继承顺序还可以,如果出现多重继承时,就会有下面的结果:
1 classBase(object):2 def __init__(self):3 print("进入Base 类")4
5
6 classA(Base):7 def __init__(self):8 print("进入A 类")9 Base.__init__(self)10
11
12 classB(Base):13 def __init__(self):14 print("进入B 类")15 Base.__init__(self)16
17
18 classC(A, B):19 def __init__(self):20 print("进入C 类")21 A.__init__(self)22 B.__init__(self)23
24
25 if __name__ == "__main__":26 c = C()
运行结果:
1 进入C 类2 进入A 类3 进入Base 类4 进入B 类5 进入Base 类6
7 Process finished with exit code 0
我们不难发现,执行顺序: C -> A -> Base -> B -> Base
是不是顺序有点蒙,我们理想状态的顺序难道不应该是: C -> A -> B -> Base (在继承多个类时,继承顺序从左往右依次继承)
如果按照理想状态运行应该怎么办, 我们就要用到 super 了。
super() 使用:
1 classBase(object):2 def __init__(self):3 print("进入Base 类")4
5
6 classA(Base):7 def __init__(self):8 print("进入A 类")9 super(A, self).__init__() # python2.7 的写法10
11
12 classB(Base):13 def __init__(self):14 print("进入B 类")15 super().__init__()16
17
18 classC(A, B):19 def __init__(self):20 print("进入C 类")21 super().__init__() # python3 继承的写法22
23
24 if __name__ == "__main__":25 c = C()
结果:
1 进入C 类2 进入A 类3 进入B 类4 进入Base 类5
6 Process finished with exit code 0
这样是不是就跟我们预想的一致了。
下面简单说一下super 是怎么运行的:
MRO
简单说一下 MRO(Method Resolution Order),中文可以叫做 方法解析顺序, 在方法调用时,需要对当前类以及基类进行搜索确定方法位置。
在程序中可以使用:
print(C.mro())
结果:
[, , , , ]
python MRO
经典类的深度遍历
python2 新式类的预计算
python3 新式类的C3线性化计算
python3 统一使用 C3 线性化算法,有兴趣的可以自行搜索。
小结
在super机制里可以保证公共父类仅被执行一次
执行的顺序,是按照MRO:方法解析顺序 进行的,执行完当前类按照mro 顺序执行下个类。