Классы-примеси (mixin) в

Введение

Примеры

  • 3

    Mixin

    Mixin представляет собой набор свойств и методов , которые могут быть использованы в различных классах, которые не приходят из базового класса. В объектно - ориентированных языках программирования, вы , как правило , использовать наследование , чтобы дать объекты различных классов ту же функциональность; если множество объектов есть некоторые способности, вы помещаете эту способность в базовом классе , что оба объекта унаследованы из.

    Например, у вас есть классы Car , Boat и Plane . Объекты из всех этих классов имеют возможность путешествовать, так что они получают функцию travel . В этом сценарии все они тоже путешествуют одинаково; получая маршрут и двигаясь по нему. Для реализации этой функции, вы можете получить все классы от Vehicle , и поставить функцию в этом разделяемой классе:

     class Vehicle(object):
       """A generic vehicle class."""
    
       def __init__(self, position):
           self.position = position
    
       def travel(self, destination):
           route = calculate_route(from=self.position, to=destination)
           self.move_along(route)
    
    class Car(Vehicle):
       ...
    
    class Boat(Vehicle):
       ...
    
    class Plane(Vehicle):
       ... 

    С помощью этого кода, вы можете позвонить в travel на автомобиле ( car.travel("Montana") ), лодки ( boat.travel("Hawaii") ), и плоскость ( plane.travel("France") )

    Однако что если у вас есть функциональность, недоступная базовому классу? Скажем, к примеру, вы хотите , чтобы Car радио и возможность использовать его , чтобы играть песню на радиостанции, с play_song_on_station , но у вас также есть Clock , которые могут использовать радио тоже. Car и Clock могут совместно использовать базовый класс ( Machine ). Однако не все машины могут воспроизводить песни; Boat и Plane не может ( по крайней мере , в данном примере). Так как же добиться успеха без дублирования кода? Вы можете использовать миксин. В Python дать классу mixin так же просто, как добавить его в список подклассов, как это

     class Foo(main_super, mixin): ... 

    Foo наследует все свойства и методы main_super , но и те из mixin , а также.

    Таким образом, чтобы дать классы для Car и Часовой возможность использовать радио, вы можете переопределить Car из предыдущего примера и написать это:

     class RadioUserMixin(object):
       def __init__(self):
           self.radio = Radio()
    
       def play_song_on_station(self, station):
           self.radio.set_station(station)
           self.radio.play_song()
    
    class Car(Vehicle, RadioUserMixin):
       ...
    
    class Clock(Vehicle, RadioUserMixin):
       ... 

    Теперь вы можете вызвать car.play_song_on_station(98.7) и clock.play_song_on_station(101.3) , но не что - то вроде boat.play_song_on_station(100.5)

    С миксинами важно то, что они позволяют вам добавлять функциональные возможности к разным объектам, которые не разделяют «основной» подкласс с этой функциональностью, но, тем не менее, совместно используют код для него. Без миксинов сделать что-то похожее на приведенный выше пример будет гораздо сложнее и / или может потребоваться некоторое повторение.

  • 3

    Переопределение методов в миксинах

    Mixins - это своего рода класс, который используется для «добавления» дополнительных свойств и методов в класс. Это обычно хорошо, потому что много раз классы mixin не переопределяют методы друг друга или базового класса. Но если вы переопределите методы или свойства в своих миксинах, это может привести к неожиданным результатам, потому что в Python иерархия классов определяется справа налево.

    Например, возьмите следующие классы

     class Mixin1(object):
        def test(self):
            print "Mixin1"
    
    class Mixin2(object):
        def test(self):
            print "Mixin2"
    
    class BaseClass(object):
        def test(self):
            print "Base"
    
    class MyClass(BaseClass, Mixin1, Mixin2):
        pass
    
     

    В этом случае класс Mixin2 является базовым классом, расширенным с помощью Mixin1 и, наконец, с помощью BaseClass. Таким образом, если мы выполним следующий фрагмент кода:

     >>> x = MyClass()
    >>> x.test()
    Base
    
     

    Мы видим возвращаемый результат из базового класса. Это может привести к непредвиденным ошибкам в логике вашего кода и должно учитываться и учитываться

Синтаксис

Параметры

Примечания