码迷,mamicode.com
首页 > 其他好文 > 详细

Day31:继承实现的原理

时间:2017-07-05 15:55:00      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:修改   str   test   需要   name   pytho   如何   子类   存在   

一、继承实现的原来

1、继承顺序

 Python的类可以继承多个类。继承多个类的时候,其属性的寻找的方法有两种,分别是深度优先广度优先

如下的结构,新式类和经典类的属性查找顺序都一致。顺序为D--->A--->E--->B--->C。

技术分享

class E:
    def test(self):
        print(from E)
class A(E):
    def test(self):
        print(from A)
class B:
    def test(self):
        print(from B)
class C:
    def test(self):
        print(from C)
class D(A,B,C):
    def test(self):
        print(from D)
d=D()
d.test()
print(D.mro())  #新式类才可以查看.mro()方法查看查找顺序
‘‘‘
from D
[<class ‘__main__.D‘>, <class ‘__main__.A‘>, <class ‘__main__.E‘>, <class ‘__main__.B‘>, <class ‘__main__.C‘>, <class ‘object‘>]
‘‘‘

如下的结构,新式类和经典类的属性查找顺序就不一样了。

经典类遵循深度优先,其顺序为:F--->E--->B--->A--->F--->C--->G--->D

新式类遵循广度优先,其顺序为:F--->E--->B--->F--->C--->G--->D--->A

技术分享

 2、继承原理

python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如:

print(D.mro())
‘‘‘
[<class ‘__main__.D‘>, <class ‘__main__.A‘>, <class ‘__main__.E‘>, <class ‘__main__.B‘>, <class ‘__main__.C‘>, <class ‘object‘>]
‘‘‘

为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:
1.子类会先于父类被检查。
2.多个父类会根据它们在列表中的顺序被检查。
3.如果对下一个类存在两个合法的选择,选择第一个父类。

 二、子类中调用父类的方法

子类继承了父类的方法,然后想进行修改,注意了是基于原有的基础上修改,那么就需要在子类中调用父类的方法。

方法一:父类名.父类方法()

技术分享
#_*_coding:utf-8_*_

class Vehicle: #定义交通工具类
     Country=China
     def __init__(self,name,speed,load,power):
         self.name=name
         self.speed=speed
         self.load=load
         self.power=power

     def run(self):
         print(开动啦...)

class Subway(Vehicle): #地铁
    def __init__(self,name,speed,load,power,line):
        Vehicle.__init__(self,name,speed,load,power)
        self.line=line

    def run(self):
        print(地铁%s号线欢迎您 %self.line)
        Vehicle.run(self)

line13=Subway(中国地铁,180m/s,1000人/箱,,13)
line13.run()
View Code

 方法二:super()

技术分享
class Vehicle: #定义交通工具类
     Country=China
     def __init__(self,name,speed,load,power):
         self.name=name
         self.speed=speed
         self.load=load
         self.power=power

     def run(self):
         print(开动啦...)

class Subway(Vehicle): #地铁
    def __init__(self,name,speed,load,power,line):
        #super(Subway,self) 就相当于实例本身 在python3中super()等同于super(Subway,self)
        super().__init__(name,speed,load,power)
        self.line=line

    def run(self):
        print(地铁%s号线欢迎您 %self.line)
        super(Subway,self).run()

class Mobike(Vehicle):#摩拜单车
    pass

line13=Subway(中国地铁,180m/s,1000人/箱,,13)
line13.run()
View Code

 不用super引发的惨案

#每个类中都继承了且重写了父类的方法
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)
f1=D()
print(D.__mro__) 
‘‘‘
D的构造方法
B的构造方法
A的构造方法
C的构造方法
A的构造方法
(<class ‘__main__.D‘>, <class ‘__main__.B‘>, <class ‘__main__.C‘>, <class ‘__main__.A‘>, <class ‘object‘>)
‘‘‘

 使用super()的结果

class A:
    def __init__(self):
        print(A的构造方法)

class B(A):
    def __init__(self):
        print(B的构造方法)
        super().__init__()    #super(B,self).__init__()
class C(A):
    def __init__(self):
        print(C的构造方法)
        super().__init__()    #super(C,self).__init__()

class D(B,C):
    def __init__(self):
        print(D的构造方法)
        super().__init__()    #super(D,self).__init__()
        # C.__init__(self)
f1=D()
print(D.__mro__)
‘‘‘
D的构造方法
B的构造方法
C的构造方法
A的构造方法
(<class ‘__main__.D‘>, <class ‘__main__.B‘>, <class ‘__main__.C‘>, <class ‘__main__.A‘>, <class ‘object‘>)
‘‘‘

 当你使用super()函数时,Python会在MRO列表上继续搜索下一个类。只要每个重定义的方法统一使用super()并只调用它一次,那么控制流最终会遍历完整个MRO列表,每个方法也只会被调用一次(注意注意注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表

三、

 

Day31:继承实现的原理

标签:修改   str   test   需要   name   pytho   如何   子类   存在   

原文地址:http://www.cnblogs.com/maple-shaw/p/7121728.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!