最近在工作中使用多继承时再次体验了一把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))