Python Language
Mixiny
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,BoatiPlane. 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 zVehiclei 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ć
travelsamochodem (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
Cari zegar możliwość korzystania z radia, możesz zastąpićCarz 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)iclock.play_song_on_station(101.3), ale nie coś takiego jakboat.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ć