Python Mixin

Mixin 实质上是利用语言特性(比如 Ruby 的 include 语法、Python 的多重继承)来更简洁地实现组合模式。

Mixin 的出现是为了解决多重继承的问题,那么多重继承到底有什么问题?

  • 结构复杂化:如果是单一继承,一个类的父类是什么,父类的父类是什么,都很明确,因为只有单一的继承关系,然而如果是多重继承的话,一个类有多个父类,这些父类又有自己的父类,那么类之间的关系就很复杂了。
  • 优先顺序模糊:假如我有 A,C 类同时继承了基类,B 类继承了 A 类,然后 D 类又同时继承了 B 和 C 类,所以 D 类继承父类的方法的顺序应该是 D、B、A、C 还是 D、B、C、A,或者是其他的顺序,很不明确。
  • 功能冲突:因为多重继承有多个父类,所以当不同的父类中有相同的方法是就会产生冲突。如果 B 类和 C 类同时有相同的方法时,D 继承的是哪个方法就不明确了,因为存在两种可能性。

什么时候需要 Mixin

有两个主要的使用 Mixin 的场景:

  • 你希望给一个类提供很多可选的特征(feature)
  • 你希望在很多不同的类中使用一个特定的特征(feature)

Mixin 又如何解决多重继承的问题

在 Python 中我们可以利用多重继承来实现 Mixin,所以 Mixin 是一种特殊的多重继承。

Mixin 类是具有以下特征的抽象类:

  • 不能单独生成实例(不可实例化)
  • 不能继承普通类

Mixin 技术按以下规则来限制多重继承:

  • 继承用单一继承
  • 第二个及两个以上的父类必须是 Mixin 的抽象类

Mixin 还有以下特点:

  • Mixin 是一个行为的集合,而这个行为可以被加到任意类里
  • Mixin 可以调用宿主类继承的其它类中的方法
  • Mixin 类是单一职责的
  • Mixin 类对宿主类一无所知
  • 宿主类的主体逻辑不会因为去掉 Mixin 而受到影响,同时也不存在超类方法调用(super)以避免引入 MRO 查找顺序问题
  • Mixin 类给宿主类提供独立的方法(函数)

从某种程度上来说,继承强调 I am,Mixin 强调 I can

一个简单的例子:

# 定义一个 Mixin 类 A 和 B,普通类 C 继承了 A 和 B

# 因为 C 同时继承了 A 和 B 类,所以在 A 类里面也可以调用 B 类中的方法,同理 B 类中也可以调用 A 类中的方法
# (因为最后实例化的是 C,而 C 又同时继承了 A 和 B,所以它当然可以调用 A 和 B 里面的方法)
>>> class A:
...     def a1(self, num):
...             print num
...     def a2(self):
...             self.b1()
...
>>> class B:
...     def b1(self):
...             print 'hello from B'
...
>>> class C(A, B):
...     def c1(self):
...             self.a1(5)
...             self.a2()
...             self.b1()
...
>>> c = C()
>>> c.c1()
5
hello from B
hello from B

参考链接

posted @ 2017-07-31 12:57  天涯海角路  阅读(349)  评论(0)    收藏  举报