Mejor manera de acceder al método de súper clase en herencia múltiple

class Animal(object): def eat(self): print("I eat all") class C(object): def eat(self): print("I too eat") class Wolf(C, Animal): def eat(self): print("I am Non Veg") super(Wolf, self).eat() Animal.eat(self) w = Wolf() w.eat() 

Estoy aprendiendo la herencia múltiple en python, quiero acceder al método Animal y C de la clase derivada utilizando super método super .

Llamada predeterminada de llamadas internas internas Método de la clase C , pero para llamar al método de la clase Animal utilicé Animal.eat(self) Mi pregunta es cómo puedo llamar al método de la clase Animal utilizando super método super .

Si desea realizar una herencia múltiple sana, necesita que todos llamen super, excepto exactamente una clase base, que tiene el deber de no llamar super. Tener dos clases base completamente independientes con el mismo método no es algo que tenga sentido usando la teoría OOP y no es algo que Python tenga las herramientas para manejar bien.

Es posible que veas dos clases base aparentemente independientes en muchos ejemplos, pero en esos casos el método de ejemplo suele ser __init__ , y la única clase base que no es de súper llamada es el object .

No puedes llamar a Animal.eat usando super . super usa la Orden de resolución de métodos (MRO) de Python para determinar a qué clase llamar, y C está eclipsando a Animal en esa MRO.

En tu ejemplo, super(Wolf, self).eat() tiene el mismo efecto que C.eat(self) . Llamar a Animal.eat(self) funciona, pero solo mientras el gráfico de herencia siga siendo el actual.

Tener que llamar a un método que no está disponible debido a la MRO es una indicación de que se debe mejorar el modelado de clase.

super se utiliza para buscar en clases para padres. En su caso, porque establece la herencia en el orden C, Animal , el orden de preferencia para la búsqueda de métodos es el siguiente:

  • primera clase para padres
  • segunda clase para padres

Así que super devolverá el método del padre más cercano.

Una observación, sin embargo, es que la búsqueda se hace primero:

 >>> class A(object): ... def t(self): ... print 'from A' >>> class B(object): ... def t(self): ... print 'from B' >>> class C(A): ... pass >>> class D(C, B): ... pass >>> d = D() >>> dt() from A 

super() usa la Orden de resolución de métodos (MRO) para determinar a qué método de superclase se llama.

La mejor manera de controlar qué método de clase en el caso de herencia múltiple es llamarlo explícitamente, sin usar super() .

O puede reordenar las superclases en la definición de subclase para cambiar el MRO. Esto le permite continuar usando super() pero sacrifica cierta legibilidad, IMO.

Ejemplo usando super() :

 class Wolf(C, Animal): def eat(self): # C.eat() comes first in the MRO super(Wolf, self).eat() 

Versus:

 class Wolf(Animal, C): def eat(self): # Animal.eat() comes first in the MRO super(Wolf, self).eat()