Szukaj…


Składnia

  • class ClassName ( MainClass , Mixin1 , Mixin2 , ...): # Używany do deklarowania klasy o nazwie ClassName , main (pierwsza) klasa MainClass i mixiny Mixin1 , Mixin2 itp.
  • class ClassName ( Mixin1 , MainClass , Mixin2 , ...): # „Główna” klasa nie musi być pierwszą klasą; naprawdę nie ma różnicy między tym a mixinem

Uwagi

Dodanie mixinu do klasy wygląda bardzo podobnie do dodania nadklasy, ponieważ tak po prostu jest. Obiekt klasy z mieszanym Foo będzie również instancją Foo , a isinstance(instance, Foo) zwróci true

Mixin

Mixin to zestaw właściwości i metod, które można stosować w różnych klasach, które nie pochodzą z klasy podstawowej. W językach programowania obiektowego zwykle używasz dziedziczenia, aby nadać obiektom różnych klas tę samą funkcjonalność; jeśli zbiór obiektów ma jakąś zdolność, umieścisz ją w klasie podstawowej, z której dziedziczą oba obiekty.

Załóżmy na przykład, że masz klasy Car , Boat i Plane . Obiekty ze wszystkich tych klas mają zdolność podróżowania, dzięki czemu otrzymują funkcję travel . W tym scenariuszu wszyscy podróżują w ten sam podstawowy sposób; wyznaczając trasę i poruszając się nią. Aby zaimplementować tę funkcję, możesz wyprowadzić wszystkie klasy z Vehicle i umieścić tę funkcję we wspólnej klasie:

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):
   ...

Za pomocą tego kodu możesz wywoływać travel samochodem ( car.travel("Montana") ), statkiem ( boat.travel("Hawaii") ) i samolotem ( plane.travel("France") )

Co jednak, jeśli masz funkcjonalność niedostępną dla klasy podstawowej? Załóżmy na przykład, chcesz dać Car radio i możliwość używania go odtworzyć utwór w radiu, z play_song_on_station , ale trzeba również Clock , który można używać radia też. Car i Clock mogą dzielić klasę podstawową ( Machine ). Jednak nie wszystkie urządzenia mogą odtwarzać utwory; Boat i Plane nie mogą (przynajmniej w tym przykładzie). Jak to zrobić bez powielania kodu? Możesz użyć mixinu. W Pythonie nadanie klasie miksu jest tak proste, jak dodanie go do listy podklas, takich jak to

class Foo(main_super, mixin): ...

Foo odziedziczy wszystkie właściwości i metody main_super , ale także właściwości mixin .

Tak więc, aby dać klasom Car i zegar możliwość korzystania z radia, możesz zastąpić Car z ostatniego przykładu i napisać to:

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):
   ...

Teraz możesz wywoływać car.play_song_on_station(98.7) i clock.play_song_on_station(101.3) , ale nie coś takiego jak boat.play_song_on_station(100.5)

Ważną rzeczą w mixinach jest to, że pozwalają one dodawać funkcjonalność do wielu różnych obiektów, które nie dzielą „głównej” podklasy z tą funkcjonalnością, ale mimo to dzielą dla niej kod. Bez mixin robienie czegoś takiego jak powyższy przykład byłoby znacznie trudniejsze i / lub wymagałoby powtórzenia.

Przesłanianie metod w mieszankach

Mixiny są rodzajem klasy, która służy do „dodawania” dodatkowych właściwości i metod do klasy. Zazwyczaj jest to w porządku, ponieważ wiele razy klasy mixin nie zastępują metod innych lub metod klasy podstawowej. Ale jeśli zastąpisz metody lub właściwości w swoich mixinach, może to prowadzić do nieoczekiwanych wyników, ponieważ w Pythonie hierarchia klas jest definiowana od prawej do lewej.

Na przykład weź następujące klasy

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

W tym przypadku klasa Mixin2 jest klasą podstawową, rozszerzoną o Mixin1 i wreszcie o BaseClass. Dlatego jeśli wykonamy następujący fragment kodu:

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

Widzimy, że zwracany wynik pochodzi z klasy Base. Może to prowadzić do nieoczekiwanych błędów w logice kodu i należy to uwzględnić i pamiętać



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow