multiple method classes python inheritance constructor init

method - python multiple inheritance



Python: hereda la superclase__init__ (7)

Tengo una clase base con muchos argumentos __init__ :

def BaseClass(object): def __init__(self, a, b, c, d, e, f, ...): self._a=a+b self._b=b if b else a ...

Todas las clases __init__ deben ejecutar el método __init__ de la clase base.

Puedo escribir un __init__() en cada una de las clases __init__ que llamarían a la superclase __init__ , pero sería una duplicación de código grave:

def A(BaseClass): def __init__(self, a, b, c, d, e, f, ...): super(A, self).__init__(a, b, c, d, e, f, ...) def B(BaseClass): def __init__(self, a, b, c, d, e, f, ...): super(A, self).__init__(a, b, c, d, e, f, ...) def C(BaseClass): def __init__(self, a, b, c, d, e, f, ...): super(A, self).__init__(a, b, c, d, e, f, ...) ...

¿Cuál es la forma más pitonica de llamar automáticamente a la superclase __init__ ?


A menos que esté haciendo algo útil en los __init__() la subclase __init__() , no tiene que anularlo.

def BaseClass(object): def __init__(self, a, b, c, d, e, f, ...): self._a=a+b self._b=b if b else a ... def A(BaseClass): def some_other_method(self): pass def B(BaseClass): pass


Agregar una implementación Pythonic. Suponiendo que desea que todos los atributos pasen, puede usar el siguiente código. (También puede mantener / eliminar claves kwargs específicas si quiere un subconjunto).

def A(BaseClass): def __init__(self, *args, **kwargs): for key, value in kwargs.items(): setattr(self, key, value) base = BaseClass(...) new = A( **base.__dict__ )


En las versiones 2.6 y inferior para heredar init de la clase base, no hay super función, puede heredar de la siguiente manera:

class NewClass(): def __init__(): BaseClass.__init__(self, *args)


Quizás una implementación más clara para su caso es usar ** kwargs combinado con nuevos argumentos agregados en su clase derivada como en:

class Parent: def __init__(self, a, b, c): self.a = a self.b = b self.c = c class Child(Parent): def __init__(self, d, **kwargs): super(Child, self).__init__(**kwargs) self.d = d

Con este método evita la duplicación de código pero conserva la adición implícita de argumentos en su clase derivada.


Si las clases derivadas no implementan nada más allá de lo que ya hace la clase base __init__() , simplemente omita las clases derivadas __init__() métodos - la clase base __init__() se llama automáticamente.

Si, OTOH, tus clases derivadas agregan algo de trabajo adicional en su __init__() , y no quieres que llamen explícitamente a su clase base __init__() , puedes hacer esto:

class BaseClass(object): def __new__(cls, a, b, c, d, e, f, ...): new = object.__new__(cls) new._a=a+b new._b=b if b else a ... return new class A(BaseClass): '''''' no __init__() at all here '''''' class B(BaseClass): def __init__(self, a, b, c, d, e, f, ...): '''''' do stuff with init params specific to B objects ''''''

Como __new__() siempre se llama automáticamente, no se requiere más trabajo en las clases derivadas.


Tienes que escribirlo explícitamente, pero, por otro lado, si tienes muchos argumentos, probablemente deberías usar * args para posicionales args y ** kwargs para palabras clave args.

class SubClass(BaseClass): def __init__(self, *args, **kwargs): super(SubClass, self).__init__(*args, **kwargs) # SubClass initialization code

Otra técnica que puede usar es minimizar el código en init y luego, al final de la función init , llamar a otra función personalizada. Luego, en la subclase, solo tiene que anular la función personalizada

class BaseClass(object): def __init__(self, *args, **kwargs): # initialization code self._a = kwargs.get(''a'') ... # custom code for subclass to override self.load() def load(): pass class SubClass(BaseClass) def load(): # SubClass initialization code ...


super(SubClass, self).__init__(...)

Considere usar * args y ** kw si ayuda a resolver su pesadilla variable.