Estoy ejecutando Python 2.5, por lo que esta pregunta puede no aplicarse a Python 3. Cuando crea una jerarquía de clases diamantinas utilizando herencia múltiple y crea un objeto de la clase derivada, Python hace Right Thing (TM). Llama al constructor para la clase derivada, luego a sus clases principales enumeradas de izquierda a derecha, y luego a los abuelos. Estoy familiarizado con Python's MRO; esa no es mi pregunta. Tengo curiosidad de cómo el objeto devuelto de súper en realidad se las arregla para comunicarse con las llamadas de super en las clases principales en el orden correcto. Considere este ejemplo de código:¿Cómo hace el "super" de Python lo correcto?
#!/usr/bin/python
class A(object):
def __init__(self): print "A init"
class B(A):
def __init__(self):
print "B init"
super(B, self).__init__()
class C(A):
def __init__(self):
print "C init"
super(C, self).__init__()
class D(B, C):
def __init__(self):
print "D init"
super(D, self).__init__()
x = D()
El código no lo intuitivo, imprime:
D init
B init
C init
A init
Sin embargo, si en comentario la llamada a super en la función init del B, ni A ni la función init del C se llama. Esto significa que la llamada de B a super es de algún modo consciente de la existencia de C en la jerarquía de clases general. Sé que super devuelve un objeto proxy con un operador get sobrecargado, pero ¿cómo el objeto devuelto por super en la definición de inicio de D'comunica la existencia de C al objeto devuelto por super en la definición de inicio de B? ¿La información que las llamadas subsiguientes de superusuario almacenan en el objeto mismo? Si es así, ¿por qué no es super en su lugar self.super?
Editar: Jekke señaló con razón que no es self.super porque super es un atributo de la clase, no una instancia de la clase. Conceptualmente, esto tiene sentido, ¡pero en la práctica el súper tampoco es un atributo de la clase! Puede probar esto en el intérprete haciendo dos clases A y B, donde B hereda de A y llama al dir(B)
. No tiene atributos super
o __super__
.
Super no es self.super porque super es una propiedad de la clase, no la instancia. (Realmente no entiendo el resto de la pregunta.) –
Irrelevante, tal vez; pero varias personas me han aconsejado que ya no utilicen Python 2.5, ya que Python 3 presenta tantas características nuevas/corrige tantos errores. – adam
Editar a '¿cómo el objeto devuelto por super en la definición de inicio de D'comunica la existencia de C al objeto devuelto por super en la definición de inicio de B'? Creo que eso es lo que estás preguntando, podría tener más sentido :) –