En el libro Python in a Nutshell (2nd Edition) hay un ejemplo que usa
clases de estilo antiguo para demostrar cómo se resuelven los métodos en el orden de resolución clásico y en
qué se diferencian con el nuevo orden.
Probé el mismo ejemplo reescribiendo el ejemplo con un nuevo estilo, pero el resultado no es diferente al obtenido con las clases de estilo antiguo. La versión de Python que estoy usando para ejecutar el ejemplo es 2.5.2. A continuación se muestra el ejemplo:
class Base1(object):
def amethod(self): print "Base1"
class Base2(Base1):
pass
class Base3(object):
def amethod(self): print "Base3"
class Derived(Base2,Base3):
pass
instance = Derived()
instance.amethod()
print Derived.__mro__
La llamada se instance.amethod()
imprime Base1
, pero según mi comprensión del MRO con un nuevo estilo de clases, la salida debería haber sido Base3
. La llamada Derived.__mro__
imprime:
(<class '__main__.Derived'>, <class '__main__.Base2'>, <class '__main__.Base1'>, <class '__main__.Base3'>, <type 'object'>)
No estoy seguro de si mi comprensión de MRO con nuevas clases de estilo es incorrecta o si estoy cometiendo un error tonto que no puedo detectar. Ayúdenme a comprender mejor el MRO.
fuente
El orden de resolución del método de Python es en realidad más complejo que solo comprender el patrón de diamante. Para entenderlo realmente , eche un vistazo a la linealización C3 . Descubrí que realmente ayuda usar declaraciones de impresión al extender métodos para rastrear el pedido. Por ejemplo, ¿cuál cree que sería el resultado de este patrón? (Nota: se supone que la 'X' son dos bordes que se cruzan, no un nodo y ^ significa métodos que llaman a super ())
¿Recibiste ABDCEFG?
Después de muchas pruebas y errores, se me ocurrió una interpretación informal de la teoría de grafos de la linealización C3 de la siguiente manera: (Alguien, por favor, avíseme si esto está mal).
Considere este ejemplo:
fuente
super
ha requerido argumentos.El resultado que obtienes es correcto. Prueba a cambiar la clase base
Base3
paraBase1
y comparar con la misma jerarquía de clases clásicas:Ahora sale:
Lea esta explicación para obtener más información.
fuente
Estás viendo ese comportamiento porque la resolución del método es primero en profundidad, no en ancho. La herencia de Dervied parece
Entonces
instance.amethod()
amethod
, por lo que se llama.Esto se refleja en
Derived.__mro__
. Simplemente repitaDerived.__mro__
y deténgase cuando encuentre el método que está buscando.fuente