python继承机制和Minxin模式
python继承和访问父类和super
python通过在类方法名旁边声明(父类名)来继承父类
子类可以通过父类名.父类成员的格式来调用父类成员,也可以使用super(子类名, self)获取到父类对象。
注意: python是多继承的, 所以可能会遇到钻石继承的问题
图片.png在钻石继承的问题中,多次调用父类成员会导致同一个超类Base被重复初始化。
python解决钻石继承的方法主要是通过super, 注意super是一个类, 并不是一个关键字
super的内核:mro
要理解super的原理,就要先了解mro。mro是method resolution order的缩写,表示了类继承体系中的成员解析顺序(可以使用mro方法输出改顺序)。
mro方法返回的是一个祖先类的列表。Leaf的每个祖先都在其中出现一次,这也是super在父类中查找成员的顺序。
通过mro,python巧妙地将多继承的图结构,转变为list的顺序结构。
super 使用实例:
super(type, obj)
当我们在Leaf的init中写这样的super时:
class Leaf(Medium1, Medium2):
def __init__(self):
super(Leaf, self).__init__()
print “Leaf init”
super(Leaf, self).init()的意思是说:
获取self所属类的mro, 也就是[Leaf, Medium1, Medium2, Base]这个序列
从mro中Leaf右边的一个类开始,依次寻找init函数。这里是从Medium1开始寻找
一旦找到,就把找到的init函数绑定到self对象,并返回
从这个执行流程可以看到,如果我们不想调用Medium1的init,而想要调用Medium2的init,那么super应该写成:super(Medium1, self)__init__
()
Minxin模式
Mixin的出现就是为了解决多重继承的问题。
Mixin的目的就是给一个类增加多个功能,这样,在设计类的时候,我们优先考虑通过多重继承来组合多个Mixin的功能,而不是设计多层次的复杂的继承关系场景参考。
例子:
Python自带的很多库也使用了Mixin。举个例子,Python自带了TCPServer
和UDPServer
这两类网络服务,而要同时服务多个用户就必须使用多进程或多线程模型,这两种模型由ForkingMixin
和ThreadingMixin
提供。通过组合,我们就可以创造出合适的服务来。
比如,编写一个多进程模式的TCP服务,定义如下:
class MyTCPServer(TCPServer, ForkingMixin):
pass
编写一个多线程模式的UDP服务,定义如下:
class MyUDPServer(UDPServer, ThreadingMixin):
pass
如果你打算搞一个更先进的TCP协程模型,可以编写一个CoroutineMixin
:
class MyTCPServer(TCPServer, CoroutineMixin):
pass
这样一来,我们不需要复杂而庞大的继承链,只要选择组合不同的类的功能,就可以快速构造出所需的子类。