Python - 多重继承
class Root:
def ping(self):
print(f'{self},ping() in Root')
def pong(self):
print(f'{self}.pong in Root')
def __repr__(self):
cls_name = type(self).__class__
return f'<instance of {cls_name}>'
class A(Root):
def ping(self):
print(f'{self},ping() in A')
super().ping()
def pong(self):
print(f'{self}.pong in A')
super().pong()
class B(Root):
def ping(self):
print(f'{self},ping() in B')
super().ping()
def pong(self):
print(f'{self}.pong in B')
class Left(A,B):
def ping(self):
print(f'{self},ping() in Left')
super().ping()
if __name__ == '__main__':
left1 = Left()
left1.ping()
'''
<instance of Left>.ping() in Left
<instance of Left>.ping() in A
<instance of Left>.ping() in B
<instance of Left>.ping() in Root
'''
唤醒过程由以下两个因素决定:
- Leaf 类的方法解析顺序
- 各方法中使用的super()
每个类都有名为__mro__
的属性,它的值是一个元组,按照方法解析顺序列出各个超类,从当前类一直到object类。
Leaf 类的 __mro__
属性如下所示:
(<class '__main__.Left'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Root'>, <class 'object'>)
if __name__ == '__main__':
left1 = Left()
left1.pong()
'''
<instance of Left>.pong in A
<instance of Left>.pong in B
'''
上列中,由于Leaf 类没有覆盖方法,因此调用left1.pong 唤醒的是Leaf.__mro__ 中下一个类(A类)实现的pong 方法. A.pong 方法调用了super().pong()。 方法解析顺序的下一个类是B,因此B.pong被唤醒。但是,因为B.pong 方法没有调用super().pong() ,所以唤醒过程到此结束
class Left(B,A):
def ping(self):
print(f'{self}.ping() in Left')
super().ping()
if __name__ == '__main__':
left1 = Left()
left1.pong()
print(Left.__mro__)
'''
<instance of Left>.pong in B
(<class '__main__.Left'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.Root'>, <class 'object'>)
'''
该列中Leaf 类声明为Leaf(B,A), 那么在Lead.__mro__ 中,B类将出现在A类前面,这会影响pong方法 的唤醒顺序,而且left1.pong() 将通过继承树唤醒B.pong,但是不唤醒A.poong 和Rootf.pong ,因为B.pong 没有调用super()
调用super() 的方法叫做协作方法。利用协作方法可以实现协作多重继承。Python中多重继承涉及多个方法的协作。在B类中ping是协作方法,而pong则不是
class LeftUA(U,A):
def ping(self):
print(f'{self}.ping() in LeftUA')
super().ping()
if __name__ == '__main__':
left3 = LeftUA()
left3.ping()
print(LeftUA.__mro__)
'''
<instance of LeftUA>.ping() in LeftUA
<instance of LeftUA>.ping() in U
<instance of LeftUA>.ping() in A
<instance of LeftUA>.ping() in Root
(<class '__main__.LeftUA'>, <class '__main__.U'>, <class '__main__.A'>, <class '__main__.Root'>, <class 'object'>)
'''
class U():
def ping(self):
print(f'{self}.ping() in U')
super().ping()
class LeftAU(A,U):
def ping(self):
print(f'{self}.ping() in LeftAU')
super().ping()
if __name__ == '__main__':
left2 = LeftAU()
left2.ping()
print(LeftAU.__mro__)
'''
<instance of LeftAU>.ping() in LeftAU
<instance of LeftAU>.ping() in A
<instance of LeftAU>.ping() in Root
(<class '__main__.LeftAU'>, <class '__main__.A'>, <class '__main__.Root'>, <class '__main__.U'>, <class 'object'>
'''
在真实的程序中,U 这样的类可以作为混入类使用。混入类意在与多重继承中的其他类结合在一起使用,提供额外的功能
本文来自博客园,作者:chuangzhou,转载请注明原文链接:https://www.cnblogs.com/czzz/p/17455443.html