标签:bar col sts lock 线性 src 重定义 一个 syn
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‘)    passf1=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):        passc=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)    passf1=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中没有这个属性 |