Buscar..


Sintaxis

  • class ClassName ( MainClass , Mixin1 , Mixin2 , ...): # Se utiliza para declarar una clase con el nombre ClassName , main (first) class MainClass y mixins Mixin1 , Mixin2 , etc.
  • class ClassName ( Mixin1 , MainClass , Mixin2 , ...): # La clase 'main' no tiene que ser la primera clase; Realmente no hay diferencia entre esto y la mezcla

Observaciones

Agregar un mixin a una clase se parece mucho a agregar una superclase, porque es más o menos eso. Un objeto de una clase con la mezcla Foo también será una instancia de Foo , e isinstance(instance, Foo) devolverá verdadero

Mezclar

Un Mixin es un conjunto de propiedades y métodos que se pueden usar en diferentes clases, que no provienen de una clase base. En los lenguajes de programación orientada a objetos, normalmente se usa la herencia para dar a los objetos de diferentes clases la misma funcionalidad; si un conjunto de objetos tiene alguna habilidad, pones esa habilidad en una clase base de la cual ambos objetos heredan .

Por ejemplo, supongamos que tiene las clases Car , Boat y Plane . Los objetos de todas estas clases tienen la capacidad de viajar, por lo que obtienen la función de travel . En este escenario, todos viajan de la misma manera básica, también; consiguiendo una ruta, y moviéndose a lo largo de ella. Para implementar esta función, podría derivar todas las clases de Vehicle y poner la función en esa clase compartida:

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 este código, puede llamar a travel en un automóvil ( car.travel("Montana") ), barco ( boat.travel("Hawaii") ), y avión ( plane.travel("France") )

Sin embargo, ¿qué sucede si tiene una funcionalidad que no está disponible para una clase base? Digamos, por ejemplo, que quieres darle a Car una radio y la posibilidad de usarla para reproducir una canción en una estación de radio, con play_song_on_station , pero también tienes un Clock que puede usar una radio. Car y Clock podrían compartir una clase base ( Machine ). Sin embargo, no todas las máquinas pueden reproducir canciones; Boat y Plane no pueden (al menos en este ejemplo). Entonces, ¿cómo lograr sin duplicar el código? Puedes usar un mixin. En Python, dar una mezcla a una clase es tan simple como agregarla a la lista de subclases, como esto

class Foo(main_super, mixin): ...

Foo heredará todas las propiedades y métodos de main_super , pero también los de mixin .

Por lo tanto, para dar a las clases Car y reloj la posibilidad de usar una radio, puede anular Car del último ejemplo y escribir esto:

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):
   ...

Ahora puedes llamar a car.play_song_on_station(98.7) y clock.play_song_on_station(101.3) , pero no a algo como boat.play_song_on_station(100.5)

Lo importante con los mixins es que le permiten agregar funcionalidad a objetos muy diferentes, que no comparten una subclase "principal" con esta funcionalidad, pero aún así comparten el código para ello. Sin los mixins, hacer algo como el ejemplo anterior sería mucho más difícil y / o podría requerir alguna repetición.

Métodos de anulación en Mixins

Los mixins son una clase de clase que se usa para "mezclar" propiedades y métodos adicionales en una clase. Por lo general, esto está bien porque muchas veces las clases mixtas no se anulan entre sí, o los métodos de la clase base. Pero si anula métodos o propiedades en sus combinaciones, esto puede llevar a resultados inesperados porque en Python la jerarquía de clases se define de derecha a izquierda.

Por ejemplo, tome las siguientes clases

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

En este caso, la clase Mixin2 es la clase base, extendida por Mixin1 y finalmente por BaseClass. Por lo tanto, si ejecutamos el siguiente fragmento de código:

>>> x = MyClass()
>>> x.test()
Base

Vemos que el resultado devuelto es de la clase Base. Esto puede provocar errores inesperados en la lógica de su código y debe tenerse en cuenta y tenerse en cuenta.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow