Necesito encontrar una manera elegante de hacer 2 tipos de MixIns.¿Cuáles son las maneras elegantes de hacer MixIns en Python?
Primero:
class A(object):
def method1(self):
do_something()
Ahora, un MixInClass
debe hacer method1
hacer esto: do_other()
->A.method1()
->do_smth_else()
- es decir, básicamente, "envolver" la función más. Estoy bastante seguro de que debe existir una buena solución para esto.
Segundo:
class B(object):
def method1(self):
do_something()
do_more()
En este caso, quiero MixInClass2
para poder inyectarse entre do_something()
y do_more()
, es decir .: do_something()
->MixIn.method1
->do_more()
. Entiendo que probablemente esto requiera modificar class B
- eso está bien, solo estoy buscando las formas más simples de lograr esto.
Estos son problemas bastante triviales y en realidad los resolví, pero mi solución está contaminada.
Fisrt uno usando self._old_method1 = self.method1(); self.method1() = self._new_method1();
y escribiendo _new_method1()
que llama a _old_method1()
.
Problema: múltiples MixIns cambiarán el nombre a _old_method1 y no es elegante.
Segundo MixIn uno se resolvió creando un método ficticio call_mixin(self): pass
e inyectándolo entre llamadas y definiendo self.call_mixin()
. De nuevo poco elegante y se romperá en múltiples MixIns ..
¿Alguna idea?
Gracias a Boldewyn, he encontrado la solución elegante al primero (he olvidado puede crear decoradores sobre la marcha, sin modificar código original):
class MixIn_for_1(object):
def __init__(self):
self.method1 = self.wrap1(self.method1)
super(MixIn_for_1, self).__init__()
def wrap1(self, old):
def method1():
print "do_other()"
old()
print "do_smth_else()"
return method1
Aún así la búsqueda para ideas para el segundo (esta idea no encajará, ya que necesito inyectar dentro del viejo método, no afuera, como en este caso).
Solución para segunda está por debajo, en sustitución de "pass_func" con lambda:0
.
Para su segunda pregunta, ¿necesita mezclar.method1 los parámetros y, de ser así, estos parámetros dependen de las variables/valores devueltos en do_something()? Y finalmente, ¿do_more() necesita el resultado de tu mixin? – KillianDS
No, do_more() no necesita resultado. ¿Los argumentos? Probablemente solo necesite "yo", lo cual debería pasar de todos modos. –