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 och Plane . Objekt från alla dessa klasser har förmågan att resa, så de får funktionen att travel . 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ån Vehicle 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ätta Car 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) och clock.play_song_on_station(101.3) , men inte något som boat.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



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow