1 继承顺序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
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 f1 = F() f1.test() print (F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性 #新式类继承顺序:F->D->B->E->C->A #经典类继承顺序:F->D->B->A->E->C #python3中统一都是新式类 #pyhon2中才分新式类与经典类 |
2 继承原理(python如何实现的继承)
python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如
1
2
|
>>> F.mro() #等同于F.__mro__ [< class ‘__main__.F‘ >, < class ‘__main__.D‘ >, < class ‘__main__.B‘ >, < class ‘__main__.E‘ >, < class ‘__main__.C‘ >, < class ‘__main__.A‘ >,<br> < class ‘object‘ >] |
为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止
合并所有父类的MRO列表并遵循如下三条准则:
1.子类会先于父类被检查
2.多个父类会根据它们在列表中的顺序被检查
3.如果对下一个类存在两个合法的选择,选择第一个父类
3 子类中调用父类方法(super()方法)
子类继承了父类的方法,然后想进行修改,注意了是基于原有的基础上修改,那么就需要在子类中调用父类的方法
方法一 父类名.父类方法()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
class People: def __init__( self ,name,sex,age): self .name = name self .sex = sex self .age = age def walk( self ): print ( ‘%s is walking‘ % self .name) class Chinese(People): country = ‘China‘ def __init__( self ,name,sex,age,language = ‘Chinses‘ ): People.__init__( self ,name,sex,age) self .language = language def walk( self ,x): pass c = Chinese( ‘xiaojing‘ , ‘male‘ , 20 ) print (c.name,c.sex,c.age,c.language) |
方法二 super()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
class People: def __init__( self ,name,sex,age): self .name = name self .age = age self .sex = sex def walk( self ): print ( ‘%s is walking‘ % self .name) class Chinese(People): country = ‘China‘ def __init__( self ,name,sex,age,language = ‘Chinese‘ ): super ().__init__(name,sex,age) #super() 绑定 调用父类方法 self .language = language def walk( self ,x): super ().walk() print ( "---->子类的x" ,x) c = Chinese( ‘EGG‘ , ‘male‘ , ‘20‘ ) c.walk( 123 ) |
不用super引发的惨案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#每个类中都继承了且重写了父类的方法 class A: def __init__( self ): print ( ‘A的构造方法‘ ) class B(A): def __init__( self ): print ( ‘B的构造方法‘ ) A.__init__( self ) class C(A): def __init__( self ): print ( ‘C的构造方法‘ ) A.__init__( self ) class D(B,C): def __init__( self ): print ( ‘D的构造方法‘ ) B.__init__( self ) C.__init__( self ) pass f1 = D() print (D.__mro__) #python2中没有这个属性 |
当你使用super()函数时,Python会在MRO列表上继续搜索下一个类。只要每个重定义的方法统一使用super()并只调用它一次,那么控制流最终会遍历完整个MRO列表,每个方法也只会被调用一次(注意注意注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#每个类中都继承了且重写了父类的方法 class A: def __init__( self ): print ( ‘A的构造方法‘ ) class B(A): def __init__( self ): print ( ‘B的构造方法‘ ) super (B, self ).__init__() class C(A): def __init__( self ): print ( ‘C的构造方法‘ ) super (C, self ).__init__() class D(B,C): def __init__( self ): print ( ‘D的构造方法‘ ) super (D, self ).__init__() f1 = D() print (D.__mro__) #python2中没有这个属性 |