Python Language
Mixins
Sök…
Syntax
- klass ClassName ( MainClass , Mixin1 , Mixin2 , ...): # Används för att förklara en klass med namnet ClassName , main (first) class MainClass och mixins Mixin1 , Mixin2 , etc.
- klass Klassnamn ( Mixin1 , MainClass , Mixin2 , ...): # "Huvudklassen" behöver inte vara första klass; det finns verkligen ingen skillnad mellan det och mixin
Anmärkningar
Att lägga till en mixin i en klass ser mycket ut som att lägga till en superklass, eftersom det ganska mycket är just det. Ett objekt i en klass med mixin Foo kommer också att vara ett exempel på Foo , och isinstance(instance, Foo)
kommer att returnera true
Blanda i
En Mixin är en uppsättning egenskaper och metoder som kan användas i olika klasser, som inte kommer från en basklass. I objektorienterade programmeringsspråk använder du vanligtvis arv för att ge objekt från olika klasser samma funktionalitet; om en uppsättning objekt har viss förmåga, lägger du den förmågan i en basklass som båda föremål ärver från.
Till exempel, säg att du har klasserna
Car
,Boat
ochPlane
. Objekt från alla dessa klasser har förmågan att resa, så de får funktionen atttravel
. I det här scenariot reser de också samma grundläggande sätt; genom att få en rutt och flytta längs den. För att implementera denna funktion kan du härleda alla klasser frånVehicle
och sätta funktionen i den delade klassen: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): ...
Med den här koden kan du ringa
travel
på en bil (car.travel("Montana")
), båt (boat.travel("Hawaii")
) och plan (plane.travel("France")
)
Men vad händer om du har funktioner som inte är tillgängliga för en basklass? Säg till exempel att du vill ge Car
en radio och möjligheten att använda den för att spela en låt på en radiostation, med play_song_on_station
, men du har också en Clock
som också kan använda en radio. Car
och Clock
kunde dela en basklass ( Machine
). Men inte alla maskiner kan spela låtar; Boat
och Plane
kan inte (åtminstone i det här exemplet). Så hur gör du utan att kopiera kod? Du kan använda en mixin. I Python är det lika enkelt att ge en klass en mixin som att lägga till den i listan med underklasser, som den här
class Foo(main_super, mixin): ...
Foo
kommer att ärva alla egenskaper och metoder för main_super
, men också egenskaperna hos mixin
.
Så för att ge klasserna
Car
och klocka möjligheten att använda en radio kan du åsidosättaCar
från det sista exemplet och skriva detta: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 kan du ringa
car.play_song_on_station(98.7)
ochclock.play_song_on_station(101.3)
, men inte något somboat.play_song_on_station(100.5)
Det viktiga med mixins är att de låter dig lägga till funktionalitet till mycket olika objekt, som inte delar en "huvud" underklass med den här funktionen men ändå delar koden för den ändå. Utan blandningar skulle det vara mycket svårare att göra något som exemplet ovan och / eller kräver viss upprepning.
Övervägande metoder i mixins
Mixins är en typ av klass som används för att "blanda in" extra egenskaper och metoder till en klass. Detta är vanligtvis bra eftersom många gånger inte mixin-klasserna åsidosätter varandras eller basklassens metoder. Men om du åsidosätter metoder eller egenskaper i dina mixins kan detta leda till oväntade resultat eftersom i Python klasshierarkin definieras höger till vänster.
Ta till exempel följande klasser
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
I detta fall är Mixin2-klassen basklassen, utökad med Mixin1 och slutligen med BaseClass. Således, om vi kör följande kodavsnitt:
>>> x = MyClass()
>>> x.test()
Base
Vi ser att det returnerade resultatet kommer från basklassen. Detta kan leda till oväntade fel i logiken för din kod och måste redovisas och hållas i åtanke