钻石继承

如果子类继承自两个单独的超类,而那两个超类又继承自同一个公共基类,那么就构成了钻石继承体系。这种继承体系很像竖立的菱形,也称作菱形继承。

class Base:
    def __init__(self, value):
        self.value = value
 
 
class One(Base):
    def __init__(self, value):
        Base.__init__(self, value)
        self.value *= 2
 
 
class Two(Base):
    def __init__(self, value):
        Base.__init__(self, value)
        self.value += 3
 
 
class Ways(One, Two):
    def __init__(self, value):
        One.__init__(self, value)
        Two.__init__(self, value)
 
foo = Ways(5)
print(foo.value)
 
8
class Base:
    def __init__(self, value):
        self.value = value
 
 
class One(Base):
    def __init__(self, value):
        Base.__init__(self, value)
        self.value *= 2
 
 
class Two(Base):
    def __init__(self, value):
        Base.__init__(self, value)
        self.value += 3
 
 
class Ways(One, Two):
    def __init__(self, value):
        Two.__init__(self, value)
        One.__init__(self, value)
        
 
foo = Ways(5)
print(foo.value)

10

通过上面我们可以看到,当Ways继承超类One  Two的时候, 其结果是遵从在调用Base的init方法时的顺序的, 后面的一次调用的结果会覆盖前面一次的结果。

如果我们要解决这个问题就要运用到super方法,根据方法解析顺序(MRO)以标准化的流程来安排超类之间的初始化顺序,以保证能够达到顶端的同时,公共基类的方法只运行一次。

class Base:
    def __init__(self, value):
        self.value = value
 
 
class One(Base):
    def __init__(self, value):
        super(One, self).__init__(value)
        self.value *= 2
 
 
class Two(Base):
    def __init__(self, value):
        super(Two, self).__init__(value)
        self.value += 3
 
 
class Ways(One, Two):
    def __init__(self, value):
        super(Ways, self).__init__(value)
 
foo = Ways(5)
print(foo.value)
 
16

这个地方所得到的答案与我们预想的不一样,为什么呢?按照我们的设想, 应该是先运行到One方法,执行后得到数值10, 然后运行到Two方法,得到数值13,但实际并不是这样。

调用Way(5)时, 程序会先运行到One,然后运行到Two,但是对于它的内部我们做的运算,它并没有执行, 就像声明函数一样,声明了但是没有调用,直到程序找到最顶端的基类Base时, 它又反向的往回调用执行,所以先执行 +3, 然后执行 *2 , 最终得到结果16。

class Base:
    def __init__(self, value):
        self.value = value
 
 
class One(Base):
    def __init__(self, value):
        super(One, self).__init__(value * 2)
 
 
class Two(Base):
    def __init__(self, value):
        super(Two, self).__init__(value + 3)
 
 
class Ways(One, Two):
    def __init__(self, value):
        super(Ways, self).__init__(value)
 
foo = Ways(5)
print(foo.value)
 
13

如果将计算写入__init__方法,则就会先计算,再往更高的位置搜索。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值