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 en Plane . Objecten uit al deze klassen kunnen reizen, zodat ze de functie travel . 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 van Vehicle 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 je Car 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) en clock.play_song_on_station(101.3) , maar niet zoiets als boat.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



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow