Python Language
Mixins
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
yPlane
. Los objetos de todas estas clases tienen la capacidad de viajar, por lo que obtienen la función detravel
. 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 deVehicle
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 anularCar
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)
yclock.play_song_on_station(101.3)
, pero no a algo comoboat.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.