Python MRO(Method Resolution Order)方法解析顺序

对于Python中多重继承不太清楚,所以看了下相关文章。

以下摘自http://www.cnblogs.com/yiranlaobaitu/p/3764422.html

如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中保留改间接共同基类数据成员的多份同名成员。
在一个类中保留间接共同基类的多份同名成员,这种现象是人们不希望出现的。C++提供虚基类(virtual base class)的方法,使得在继承间接共同基类时只保留一份成员。

C++在存在多个同名成员时,会报错,如

#include <iostream>
using namespace std;

class A{
    public:
    void method(){
        cout<<"A"<<endl;
    }
};

class B: public A{
};

class C{
    public:
    void method(){
        cout<<"C"<<endl;
    }
};

class D: public B, public C{
};

int main(){
    D d;
    d.method():
}

或者

#include <iostream>
using namespace std;

class A{
    public:
    void method(){
        cout<<"A"<<endl;
    }
};

class B: public A{
};

class C: public A{
};

class D: public B, public C{
};

int main(){
    D d;
    d.method():
}

编译就会报错

error: request for member 'method' is ambiguous

正确的写法应该是用virtual class

#include <iostream>
using namespace std;

class A{
    public:
    void method(){
        cout<<"A"<<endl;
    }
};

class B: virtual public A{
};

class C: virtual public A{
};

class D: public B, public C{
};

int main(){
    D d;
    d.method():
}

和C++不同,Python在多重继承时中可以存在多个同名成员

class A:
    def __init__(self):
        print 'A'

class B(A):
    pass

class C(A):
    pass

class D(B, C):
    pass

d = D()

python中采用MRO来处理这种二义性问题。
MRO的起源可以参考这篇文章:http://python.jobbole.com/85685/
这里只总结了下结论

Python2.2以前的版本:经典类时代,深度优先搜索
Python2.2版本:经典类MRO为深度优先搜索,新式类MRO为BFS
Python2.3到Python2.7:经典类和新式类采用C3算法
MRO
Python3:只有新式类,算法依然是C3算法

那么,什么是C3算法呢?

用C1C2…CN来记录类[C1, C2, …, CN]
另C是从B1, B2, …, BN继承,我们需要计算C的linearization L[C],

L[C(B1,…BN)] = C + merge(L[B1]L[B2]…L[BN], B1…BN)

且L[object] = object

看官网上的公式没明白那个merge是什么,后来从上面的链接看到,其实就是拓扑排序!

假设继承关系如下:

class D(object):
    pass

class E(object):
    pass

class F(object):
    pass

class C(D, F):
    pass

class B(E, D):
    pass

class A(B, C):
    pass

if __name__ == '__main__':
    print A.__mro__

得到
这里写图片描述

在新式类中,可以用super()来调用继承过来的方法,但需要注意的是,super()并不是调用父类,而是调用的继承顺序的下一个类,super()的第一个参数也可以是继承链中的任意一个类。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值