En django.utils.functional.py
:
for t in type(res).mro(): # <----- this
if t in self.__dispatch:
return self.__dispatch[t][funcname](res, *args, **kw)
No entiendo mro()
. ¿Qué hace y qué significa "mro"?
python
method-resolution-order
zjm1126
fuente
fuente
Respuestas:
Seguir a lo largo...:
Mientras tengamos una sola herencia,
__mro__
es solo la tupla de: la clase, su base, la base de su base, y así sucesivamente hastaobject
(solo funciona para clases de estilo nuevo, por supuesto).Ahora, con herencia múltiple ...:
... también tiene la seguridad de que, en
__mro__
, ninguna clase está duplicada, y ninguna clase viene después de sus antepasados, salvo que las clases que primero ingresan al mismo nivel de herencia múltiple (como B y C en este ejemplo) están en el__mro__
de izquierda a derecha.Cada atributo que obtiene en la instancia de una clase, no solo los métodos, se busca conceptualmente a lo largo del
__mro__
, por lo que, si más de una clase entre los antepasados define ese nombre, esto le indica dónde se encontrará el atributo, en la primera clase en el__mro__
que define ese nombre.fuente
mro
puede ser personalizado por una metaclase, se llama una vez en la inicialización de la clase y el resultado se almacena en__mro__
- ver docs.python.org/library/… .mro()
significa Método de resolución de la orden. Devuelve una lista de tipos de los que se deriva la clase, en el orden en que se buscan los métodos.mro () o __mro__ solo funciona en nuevas clases de estilo. En python 3, funcionan sin ningún problema. Pero en Python 2 esas clases necesitan heredar
object
.fuente
Esto quizás muestre el orden de resolución.
y la respuesta sería
La regla es primero en profundidad, lo que en este caso significaría D, B, A, C.
Python normalmente usa un primer orden de profundidad cuando busca clases heredadas, pero cuando dos clases heredan de la misma clase, Python elimina la primera mención de esa clase de mro.
fuente
El orden de resolución será diferente en la herencia de diamantes.
fuente
class B3
pero en el segundo caso se vaclass A
despuésclass B1