2011-06-09 19 views
6

tengo una clase:Mixins, multi-herencia, constructores, y los datos

class A(object): 
    def __init__(self, *args): 
     # impl 

También un "mixin", básicamente, otra clase con algunos datos y métodos:

class Mixin(object): 
    def __init__(self): 
     self.data = [] 

    def a_method(self): 
     # do something 

Ahora puedo crear una subclase de a con el mixin:

class AWithMixin(A, Mixin): 
    pass 

Mi problema es que quiero que los constructores de a y mixin tanto llaman. Consideré darle a AWithMixin un constructor propio, en el que se llamaba al súper, pero los constructores de las súper clases tienen diferentes listas de argumentos. ¿Cuál es la mejor resolución?

+1

¿Qué impide que llame a los dos constructores de las clases base (con su ar apropiado? guments) de 'AWithMixin .__ init__'? – NPE

+0

Esto ya ha sido respondido en profundidad. Ver http://stackoverflow.com/a/6100595/763269 –

Respuesta

8

Soy bastante nuevo a la POO también, pero ¿cuál es el problema en este código:

class AWithMixin(A, Mixin): 
    def __init__(self, *args): 
     A.__init__(self, *args) 
     Mixin.__init__(self) 
+2

esa es la mejor solución y siempre la uso. Sin embargo, si tanto 'A' como 'Mixin' amplían alguna clase (por ej. 'Base') y ambos llaman' Base .__ init __() 'puede ser obligatorio usar la función [super()] (http: // stackoverflow. com/q/576169). Es complicado en mi humilde opinión y recomiendo saber, pero evitarlo si es posible. – brandizzi

+0

@brandizzi, como dije en la respuesta, soy nuevo en OOP. Miré la función súper, pero no entendí. Si dije en esta clase [código] super (AWithMixin, self) .__ init __() [/ code], ¿cómo puedo llamar a A .__ init__ y Mixin .__ init__ ambos? Y especifica diferentes argumentos? – utdemir

+1

El problema es que esta solución no es particularmente extensible, e ignora por completo el punto de encapsulación, y especifica la mezcla en el orden incorrecto. Si desea anular los métodos en un mixin, ese mixin toma el control de ese método y debe ser responsable de llamar al mismo método en una súper clase. El hecho de que mixin tome una lista de argumentos diferente sugiere que está codificado incorrectamente/no se diseñó para su uso con esta clase de niños - es una violación de [LSP] (http://en.wikipedia.org/wiki/Liskov_substitution_principle)) . – quodlibetor

10
class A_1(object): 
    def __init__(self, *args, **kwargs): 
     print 'A_1 constructor' 
     super(A_1, self).__init__(*args, **kwargs) 

class A_2(object): 
    def __init__(self, *args, **kwargs): 
     print 'A_2 constructor' 
     super(A_2, self).__init__(*args, **kwargs) 

class B(A_1, A_2): 
    def __init__(self, *args, **kwargs): 
     super(B, self).__init__(*args, **kwargs) 
     print 'B constructor' 

def main(): 
    b = B() 
    return 0 

if __name__ == '__main__': 
    main() 
  1. A_1 constructor
  2. A_2 constructor
  3. B constructor