Плагины и расширения классов

Введение

Примеры

  • 6

    Примеси

    В объектно-ориентированном языке программирования 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.
    
     
  • 2

    Плагины с настроенными классами

    В Python 3.6, РЕР 487 добавил __init_subclass__ специального метода, который упрощает и расширяет класс настройку без использования метаклассов . Следовательно, эта функция позволяет создавать простой плагины . Здесь мы демонстрируем эту функцию путем изменения предварительного примера :

     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]
    
     

Синтаксис

Параметры

Примечания