1: 混入类(Mixins)
在面向对象编程语言中,混入类(Mixin)是一种包含方法的类,这些方法可供其他类使用,而无需成为这些类的父类。其他类如何访问混入类的方法取决于所使用的语言。
混入类提供了一种多重继承的机制,允许多个类使用公共功能,但避免了多重继承复杂的语义。当程序员希望在不同类之间共享功能时,混入类非常有用。与其一遍又一遍地重复相同的代码,不如将公共功能简单地组合到一个混入类中,然后继承到每个需要它的类中。
当我们使用多个混入类时,混入类的顺序很重要。以下是一个简单的例子:
class Mixin1(object):
def test(self):
print("Mixin1")
class Mixin2(object):
def test(self):
print("Mixin2")
class MyClass(Mixin1, Mixin2):
pass
在这个例子中,我们调用MyClass的test方法:
>>> obj = MyClass()
>>> obj.test()
Mixin1
结果必须是Mixin1,因为顺序是从左到右。当与超类一起使用时,这可能会产生意外的结果。因此,反转顺序可能更好,就像这样:
class MyClass(Mixin2, Mixin1):
pass
结果将是:
>>> obj = MyClass()
>>> obj.test()
Mixin2
混入类可以用来定义自定义插件。
class Base(object):
def test(self):
print("Base.")
class PluginA(object):
def test(self):
super().test()
print("Plugin A.")
class PluginB(object):
def test(self):
super().test()
print("Plugin B.")
plugins = PluginA, PluginB
class PluginSystemA(PluginA, Base):
pass
class PluginSystemB(PluginB, Base):
pass
PluginSystemA().test()
# Base.
# Plugin A.
PluginSystemB().test()
# Base.
# Plugin B.
- 在Python中,类的继承顺序是从左到右的。因此,当多个混入类被继承时,最左边的混入类的方法会优先被调用。
- 使用super()可以在调用当前类的方法时,自动调用父类的同名方法。这在混入类中非常有用,可以实现方法的链式调用。
2: 使用自定义类的插件
在Python 3.6中,PEP 487添加了__init_subclass__特殊方法,该方法简化并扩展了类定制,而无需使用元类。因此,此功能允许创建简单的插件。以下示例通过修改之前的代码来演示此功能:
Python 3.x 版本 ≥ 3.6
class Base:
plugins = []
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls.plugins.append(cls)
def test(self):
print("Base.")
class PluginA(Base):
def test(self):
super().test()
print("Plugin A.")
class PluginB(Base):
def test(self):
super().test()
print("Plugin B.")
结果:
PluginA().test()
# Base.
# Plugin A.
PluginB().test()
# Base.
# Plugin B.
Base.plugins
# [__main__.PluginA, __main__.PluginB]
- __init_subclass__方法在每次创建子类时被调用。这使得我们可以在子类被创建时自动将子类添加到Base类的plugins列表中。
- 这种方法提供了一种简单的方式来注册插件类,而无需手动维护插件列表。
- 使用super().test()确保在调用子类的test方法时,父类的test方法也会被调用,从而实现方法的链式调用。