super
está diseñado para esta situación, pero solo funciona si lo usa de forma coherente. Si las clases base tampoco usan super
, no funcionará, y a menos que el método esté en object
, debe usar algo así como una clase base común para finalizar la cadena de llamadas super
.
class FooBase(object):
def foo(self): pass
class A(FooBase):
def foo(self):
super(A, self).foo()
print 'A.foo()'
class B(FooBase):
def foo(self):
super(B, self).foo()
print 'B.foo()'
class C(A, B):
def foo(self):
super(C, self).foo()
print 'C.foo()'
@Marcin pregunta por qué tiene que haber una base común:
Sin FooBase
que implementa foo
pero no llama super()
la última clase que llaman super()
obtendrá un error atributo ya que no hay método base para llamar.
Si hubo clases base separadas class A(AFooBase):
y class B(BFooBase):
la llamada super()
en A
llamaría el método en el AFooBase
y el método de B
nunca ser llamado. Cuando la base es común a todas las clases, va al final del orden de resolución del método y puede estar seguro de que no importa cómo se definan las clases, el método de clase base será el último llamado.
Gracias por la respuesta. Ahora ya no me siento sucio por no usar super(). – sayap
Si bien llamar explícitamente a los métodos de clase base * puede * funcionar para escenarios muy simples como el ejemplo del cuestionario, se descompondrá si las clases base heredan de una base común y no desea que se llame dos veces al método de la clase base definitiva . Esto se conoce como "herencia de diamantes" y es un gran problema para muchos sistemas de herencia múltiple (como en C++). La herencia múltiple colaborativa de Python (con 'super()') le permite resolverla fácilmente en muchos casos (aunque eso no quiere decir que una jerarquía de herencia múltiple cooperativa sea fácil de diseñar o siempre sea una buena idea). – Blckknght