Python Language
mixins
Ricerca…
Sintassi
- class ClassName ( MainClass , Mixin1 , Mixin2 , ...): # Usato per dichiarare una classe con il nome ClassName , main (first) class MainClass e mixins Mixin1 , Mixin2 , ecc.
- class ClassName ( Mixin1 , MainClass , Mixin2 , ...): # La classe 'main' non deve essere la prima classe; non c'è davvero differenza tra esso e il mixin
Osservazioni
Aggiungere un mixin a una classe assomiglia molto all'aggiunta di una superclasse, perché praticamente è solo questo. Un oggetto di una classe con il mixin Foo sarà anche un'istanza di Foo , e isinstance(instance, Foo)
restituirà true
mixin
Un Mixin è un insieme di proprietà e metodi che possono essere utilizzati in classi diverse, che non provengono da una classe base. Nei linguaggi di programmazione orientata agli oggetti, in genere si utilizza l' ereditarietà per assegnare agli oggetti di classi diverse la stessa funzionalità; se un insieme di oggetti ha delle capacità, metti quell'abilità in una classe base da cui entrambi gli oggetti ereditano .
Ad esempio, supponi di avere le classi
Car
,Boat
ePlane
. Gli oggetti di tutte queste classi hanno la possibilità di viaggiare, quindi ottengono la funzione ditravel
. In questo scenario, viaggiano tutti allo stesso modo di base; ottenendo un percorso e muovendolo lungo Per implementare questa funzione, è possibile derivare tutte le classi daVehicle
e inserire la funzione in tale classe condivisa: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): ...
Con questo codice è possibile chiamare il
travel
su un'auto (car.travel("Montana")
), barca (boat.travel("Hawaii")
), e plane (plane.travel("France")
)
Tuttavia, cosa succede se si dispone di funzionalità che non sono disponibili per una classe base? Per esempio, vuoi dare a Car
una radio e la possibilità di usarla per suonare una canzone su una stazione radio, con play_song_on_station
, ma hai anche un Clock
che può usare anche una radio. Car
e Clock
potrebbero condividere una classe base ( Machine
). Tuttavia, non tutte le macchine possono riprodurre canzoni; Boat
e Plane
non possono (almeno in questo esempio). Quindi come realizzi senza duplicare il codice? Puoi usare un mixin. In Python, dare una lezione a un mixin è semplice come aggiungerlo alla lista delle sottoclassi, come questa
class Foo(main_super, mixin): ...
Foo
erediterà tutte le proprietà e i metodi di main_super
, ma anche quelli di mixin
.
Quindi, per dare alle classi
Car
e orologio la possibilità di usare una radio, potresti sovrascrivereCar
dall'ultimo esempio e scrivere questo: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): ...
Ora puoi chiamare
car.play_song_on_station(98.7)
eclock.play_song_on_station(101.3)
, ma non qualcosa comeboat.play_song_on_station(100.5)
La cosa importante con i mixin è che ti permettono di aggiungere funzionalità a oggetti molto diversi, che non condividono una sottoclasse "principale" con questa funzionalità, ma comunque ne condividono comunque il codice. Senza mixin, fare qualcosa come l'esempio sopra sarebbe molto più difficile e / o potrebbe richiedere alcune ripetizioni.
Metodi di sovrascrittura in Mixins
Le mixine sono una sorta di classe che viene utilizzata per "mescolare" proprietà e metodi extra in una classe. Questo di solito va bene perché molte volte le classi di mixin non si sovrappongono l'una all'altra, o i metodi della classe base. Ma se si sostituiscono metodi o proprietà nei propri mix, ciò può portare a risultati imprevisti perché in Python la gerarchia delle classi è definita da destra a sinistra.
Ad esempio, prendi le seguenti classi
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
In questo caso la classe Mixin2 è la classe base, estesa da Mixin1 e infine da BaseClass. Pertanto, se eseguiamo il seguente frammento di codice:
>>> x = MyClass()
>>> x.test()
Base
Vediamo che il risultato restituito è dalla classe Base. Ciò può portare a errori imprevisti nella logica del codice e deve essere tenuto in considerazione e tenuto presente