Python LanguageПлагины и расширения

Примеси

В объектно-ориентированном языке программирования mixin - это класс, который содержит методы для использования другими классами, не будучи родительским классом этих других классов. Как другие классы получают доступ к методам mixin, зависит от языка.

Он обеспечивает механизм множественного наследования, позволяя нескольким классам использовать общую функциональность, но без сложной семантики множественного наследования. Миксины полезны, когда программист хочет разделить функциональность между разными классами. Вместо повторения одного и того же кода снова и снова, общая функциональность может быть просто сгруппирована в 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

Микшины могут использоваться для определения пользовательских плагинов.

Python 3.x 3.0
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 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]