优秀的编程知识分享平台

网站首页 > 技术文章 正文

python散装笔记——147: 插件和扩展类

nanyue 2025-03-03 19:34:46 技术文章 8 ℃

1: 混入类(Mixins)

在面向对象编程语言中,混入类(Mixin)是一种包含方法的类,这些方法可供其他类使用,而无需成为这些类的父类。其他类如何访问混入类的方法取决于所使用的语言。

混入类提供了一种多重继承的机制,允许多个类使用公共功能,但避免了多重继承复杂的语义。当程序员希望在不同类之间共享功能时,混入类非常有用。与其一遍又一遍地重复相同的代码,不如将公共功能简单地组合到一个混入类中,然后继承到每个需要它的类中。

当我们使用多个混入类时,混入类的顺序很重要。以下是一个简单的例子:

class Mixin1(object):
  def test(self):
    print("Mixin1")

class Mixin2(object):
  def test(self):
    print("Mixin2")

class MyClass(Mixin1, Mixin2):
  pass

在这个例子中,我们调用MyClasstest方法:

>>> 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方法也会被调用,从而实现方法的链式调用。
最近发表
标签列表