再次理解python多继承mro的深度优先

最近在工作中使用多继承时再次体验了一把mro,最近工作中遇到的

简化以下代码结构既可以写出一个小例子,如下

class A(object):
    def __init__(self, params):
        self.a_name = 'name_a_{}'.format(params['name'])
        self.a_age = 'age_a_{}'.format(params['age'])

    def a_test(self):
        print('my name is:{},age is:{}'.format(self.a_name, self.a_age))


class B(object):
    def __init__(self, params):
        self.b_name = 'name_b_{}'.format(params['name'])
        self.b_age = 'age_b_{}'.format(params['age'])

    def b_test(self):
        print('my name is:{},age is:{}'.format(self.b_name, self.b_age))


class Temp(B):
    pass


class C(Temp, A):
    def __init__(self, params):
        super(C, self).__init__(params)
        super(Temp, self).__init__(params)#当时也没有多想,此时的mro顺序以为就是C->Temp->A->object

    def test_params(self):
        print('test_params,name:{},age:{}'.format(self.b_name, self.b_age))


test = C({
    
    'name': 'mingtiannihao', 'age': 23})
test.a_test()

运行结果如下,靠,竟然说没有a_name这个属性,不是继承的嘛???python
在这里插入图片描述
后来将C的mro顺序打印出来看了一下,结果恰恰和我预想的有一点不一样,尴尬!!!因为此时的Temp此时还有一个父类B,所以根据mro搜索原则,C正确的mro顺序为:

print(C.__mro__())

结果如下:

(<class '__main__.C'>, <class '__main__.Temp'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)

再次印证了mro的搜索顺序采用的是深度优先算法(python3.x采用的C3算法)
所以我们可以作出以下修改:
1.第一种该法,在类Temp中直接初始化类A的__init__()函数:

class A(object):
    def __init__(self, params):
        self.a_name = 'name_a_{}'.format(params['name'])
        self.a_age = 'age_a_{}'.format(params['age'])

    def a_test(self):
        print('my name is:{},age is:{}'.format(self.a_name, self.a_age))


class B(object):
    def __init__(self, params):
        self.b_name = 'name_b_{}'.format(params['name'])
        self.b_age = 'age_b_{}'.format(params['age'])

    def b_test(self):
        print('my name is:{},age is:{}'.format(self.b_name, self.b_age))


class Temp(B):
    def __init__(self, params):
        super(B, self).__init__(params)#说明一点,这样写的话,类Temp的话就不能单独实例了,因为单独实例Temp的话,mro顺序B之后就是object了


class C(Temp, A):
    def __init__(self, params):
        super(C, self).__init__(params)
        # super(Temp, self).__init__(params)

    def test_params(self):
        print('test_params,name:{},age:{}'.format(self.b_name, self.b_age))


test = C({
    
    'name': 'mingtiannihao', 'age': 23})
test.a_test()

运行结果如下:
在这里插入图片描述
2.第二种改法,即此时我们就不继承Temp类了,而改为直接继承类B:

class C(Temp, A):
    def __init__(self, params):
        super(C, self).__init__(params)
        super(B, self).__init__(params)

    def test_params(self):
        print('test_params,name:{},age:{}'.format(self.b_name, self.b_age))

以后要是遇到了比较复杂的继承关系,我们可以先用类名.mro()先看看,当前类的mro顺序到底是怎么样的,免得出一些很奇怪的问题

猜你喜欢

转载自blog.csdn.net/mingtiannihaoabc/article/details/103578613