在Python面向对象编程中,有一个约定俗成的Mixin。Python作为一种动态语言,和C++一样都支持多重继承,但是Python也可以像Java(不支持多重继承)一样通过接口来实现多重继承,Mixin相当于Java中的接口,但是可以带实现的接口。
假如要设计Animal顶层父类,用以来实现Dog/Parrot/Ostrich。假如按种属,用Java的方式来实现。
首先实现运动方式的接口,因为不是所有的鸟类都会飞,Parrot(鹦鹉)会飞,Ostrich鸵鸟只会跑。
1 2 3 4 5 6 7
|
interface Runnable{ public void run(); }
interface Flyable { public void fly(); }
|
接着实现动物类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
class Animal{ public Animal(){} }
class Mammal{ public Mammal(){} }
class Bird{ public Bird(){} }
|
现在需要实现Bat(蝙蝠),会飞会跑的。
1 2 3 4 5 6 7 8 9 10 11
|
class Bat extends Mammal implements Runnable, Flyable{ public Bat(){} public void fly{}{ ... } public void run(){ ... } }
|
那么,按照Java的实现,我们可以先写两个Mixin类
1 2 3 4 5 6 7 8 9
|
class FlyMixin(object): def fly(self): raise NotImplementedError("")
class RunMixin(object): def run(self): raise NotImplementedError("")
|
实现狗Dog和蝙蝠Bat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
class Animal(object): pass class Mammal(object): pass class Bird(object): pass
class Dog(Mammal, RunMixin):
def __init__(self): super(Dog, self).__init__()
def run(self): pass
class Bat(Bird, RunMixin, FlyMixin):
def __init__(self): super(Bat, self).__init__()
def run(self): pass
def fly(self): pass
|
用Mixin的好处就很明显了,通过接口来拓展类的功能,而不是通过继承多个父类类拓展和丰富类的功能。对于类的一些功能,考虑通过继承Mixin这种组合模式来实现,很显然能提高代码的可拓展性。即使去掉了Mixin类的继承,也不会影响原生类的功能。
在标准库中有一些经典的Mixin例子,比如SockerServer中的ThreadingMixin,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
class ThreadingMixIn:
"""Mix-in class to handle each request in a new thread."""
|
以及Flask-Login插件中的UserMixin:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
class UserMixin(object): ''' This provides default implementations for the methods that Flask-Login expects user objects to have. '''
if not PY2:
|