首页 > 编程语言 > 详细

python继承实现的原理

时间:2017-10-03 23:59:02      阅读:421      评论:0      收藏:0      [点我收藏+]

 

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中没有这个属性

 

 
(0)
(0)
   
举报
评论 一句话评论(0
分享档案
最新文章
教程昨日排行
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!