subclases polimorfismo multiple multiherencia hijas herencia ejercicio definicion clases python inheritance python-3.x multiple-inheritance

polimorfismo - Herencia mĂșltiple en python3 con diferentes firmas



subclases python (1)

No use super(baseclass, ...) menos que sepa lo que está haciendo. El primer argumento de super() le dice qué clase omitir cuando se busca el siguiente método a usar. Por ejemplo, super(A, ...) mirará el MRO, encontrará A y luego comenzará a buscar __init__ en la siguiente clase de base, no A sí. Para C , el MRO es (C, A, B, object) , por lo que super(A, self).__init__ encontrará B.__init__ .

Para estos casos, no desea utilizar la herencia cooperativa, sino que haga referencia directamente a A.__init__ y B.__init__ . super() solo se debe usar si los métodos a los que llama tienen la misma firma o **vargs argumentos no compatibles con *args y **vargs . En ese caso, solo se necesitaría una llamada super(C, self).__init__() y la siguiente clase en la orden MRO se encargaría de encadenar la llamada.

Poniéndolo de manera diferente: cuando usas super() , no puedes saber qué clase será la siguiente en el MRO, por lo que esa clase soporta mejor los argumentos que le pasas. Si ese no es el caso, no use super() .

Llamando a los métodos base __init__ directamente:

class A(object): def __init__(self, a, b): print(''Init {} with arguments {}''.format(self.__class__.__name__, (a, b))) class B(object): def __init__(self, q): print(''Init {} with arguments {}''.format(self.__class__.__name__, (q))) class C(A, B): def __init__(self): # Unbound functions, so pass in self explicitly A.__init__(self, 1, 2) B.__init__(self, 3)

Usando cooperativo super() :

class A(object): def __init__(self, a=None, b=None, *args, **kwargs): super().__init__(*args, **kwargs) print(''Init {} with arguments {}''.format(self.__class__.__name__, (a, b))) class B(object): def __init__(self, q=None, *args, **kwargs): super().__init__(*args, **kwargs) print(''Init {} with arguments {}''.format(self.__class__.__name__, (q))) class C(A, B): def __init__(self): super().__init__(a=1, b=2, q=3)

Tengo tres clases: A , B y C

C hereda de A y B (en este orden). Las firmas constructoras de A y B son diferentes. ¿Cómo puedo llamar a los métodos __init__ de ambas clases para padres?

Mi esfuerzo en el código:

class A(object): def __init__(self, a, b): super(A, self).__init__() print(''Init {} with arguments {}''.format(self.__class__.__name__, (a, b))) class B(object): def __init__(self, q): super(B, self).__init__() print(''Init {} with arguments {}''.format(self.__class__.__name__, (q))) class C(A, B): def __init__(self): super(A, self).__init__(1, 2) super(B, self).__init__(3) c = C()

produce el error:

Traceback (most recent call last): File "test.py", line 16, in <module> c = C() File "test.py", line 13, in __init__ super(A, self).__init__(1, 2) TypeError: __init__() takes 2 positional arguments but 3 were given

Encontré este recurso que explica la herencia múltiple con diferentes conjuntos de argumentos, pero sugieren utilizar *args y **kwargs para usar para todos los argumentos. Considero que esto es muy feo, ya que no puedo ver en la clase del constructor en la clase secundaria qué tipo de parámetros transfiero a las clases primarias.