Python Language
mixins
Zoeken…
Syntaxis
- class ClassName ( MainClass , Mixin1 , Mixin2 , ...): # Gebruikt om een klasse aan te geven met de naam ClassName , main (eerste) klasse MainClass en mixins Mixin1 , Mixin2 , enz.
- class ClassName ( Mixin1 , MainClass , Mixin2 , ...): # De 'hoofdklasse' hoeft niet de eerste klasse te zijn; er is echt geen verschil tussen het en de mixin
Opmerkingen
Het toevoegen van een mixin aan een klasse lijkt veel op het toevoegen van een superklasse, omdat het eigenlijk precies dat is. Een object van een klasse met de mixin Foo zal ook een instantie van Foo zijn , en isinstance(instance, Foo)
zal waar terugkeren
mixin
Een mixin is een set eigenschappen en methoden die in verschillende klassen kunnen worden gebruikt en die niet uit een basisklasse komen. In Object Oriented Programming-talen gebruikt u meestal overerving om objecten van verschillende klassen dezelfde functionaliteit te geven; als een set objecten enige vaardigheid heeft, plaatst u die vaardigheid in een basisklasse waarvan beide objecten erven .
Stel bijvoorbeeld dat u de klassen
Car
,Boat
enPlane
. Objecten uit al deze klassen kunnen reizen, zodat ze de functietravel
. In dit scenario reizen ze allemaal ook op dezelfde eenvoudige manier; door een route te krijgen en erlangs te gaan. Om deze functie te implementeren, kunt u alle klassen vanVehicle
afleiden en de functie in die gedeelde klasse plaatsen: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): ...
Met deze code kunt u
travel
met een auto (car.travel("Montana")
), boot (boat.travel("Hawaii")
) en vliegtuig (plane.travel("France")
)plane.travel("France")
Wat als u echter functionaliteit hebt die niet beschikbaar is voor een basisklasse? Stel bijvoorbeeld dat je Car
een radio wilt geven en de mogelijkheid wilt geven om een nummer op een radiostation te spelen met play_song_on_station
, maar je hebt ook een Clock
die ook een radio kan gebruiken. Car
en Clock
kunnen een basisklasse delen ( Machine
). Niet alle machines kunnen echter nummers afspelen; Boat
en Plane
kunnen dit niet (althans in dit voorbeeld). Dus hoe bereik je het zonder code te dupliceren? Je kunt een mixin gebruiken. In Python is het geven van een mix aan een klasse net zo eenvoudig als het toevoegen aan de lijst met subklassen, zoals deze
class Foo(main_super, mixin): ...
Foo
zal alle eigenschappen en methoden van main_super
, maar ook die van mixin
.
Dus, om de klassen
Car
en klok de mogelijkheid te geven om een radio te gebruiken, zou jeCar
van het laatste voorbeeld kunnen vervangen en dit schrijven: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): ...
Nu kun je
car.play_song_on_station(98.7)
enclock.play_song_on_station(101.3)
, maar niet zoiets alsboat.play_song_on_station(100.5)
Het belangrijkste bij mixins is dat ze je in staat stellen om functionaliteit toe te voegen aan veel verschillende objecten, die geen "hoofd" subklasse delen met deze functionaliteit maar toch de code ervoor delen. Zonder mixins zou het doen van iets als het bovenstaande voorbeeld veel moeilijker zijn en / of misschien enige herhaling vereisen.
Overheersende methoden in Mixins
Mixins zijn een soort klasse die wordt gebruikt om extra eigenschappen en methoden in een klasse te 'mixen'. Dit is meestal prima, omdat de mixin-klassen elkaars of de basismethoden vaak niet overschrijven. Maar als u methoden of eigenschappen in uw mixins overschrijft, kan dit leiden tot onverwachte resultaten omdat in Python de klassenhiërarchie van rechts naar links wordt gedefinieerd.
Neem bijvoorbeeld de volgende lessen
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 dit geval is de Mixin2-klasse de basisklasse, uitgebreid met Mixin1 en ten slotte met BaseClass. Dus als we het volgende codefragment uitvoeren:
>>> x = MyClass()
>>> x.test()
Base
We zien dat het geretourneerde resultaat uit de Base-klasse komt. Dit kan leiden tot onverwachte fouten in de logica van uw code en moet worden verantwoord en in gedachten worden gehouden