¿Qué hace “mro ()”?

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”?

Seguir a lo largo…:

 >>> class A(object): pass ... >>> A.__mro__ (, ) >>> class B(A): pass ... >>> B.__mro__ (, , ) >>> class C(A): pass ... >>> C.__mro__ (, , ) >>> 

Mientras tengamos una herencia única, __mro__ es solo la tupla de: la clase, su base, la base de su base, y así sucesivamente hasta el object (solo funciona para clases de nuevo estilo, por supuesto).

Ahora, con herencia múltiple …:

 >>> class D(B, C): pass ... >>> D.__mro__ (, , , , ) 

… también obtiene la seguridad de que, en __mro__ , ninguna clase está duplicada, y ninguna clase viene después de sus ancestros, excepto que las clases que ingresan primero al mismo nivel de herencia múltiple (como B y C en este ejemplo) están en el __mro__ izquierda a derecha.

Cada atributo que obtiene en la instancia de una clase, no solo los métodos, se busca conceptualmente a lo largo de __mro__ , por lo tanto, si más de una clase entre los ancestros define ese nombre, esto le indica dónde se encontrará el atributo: en la primera clase en el __mro__ que define ese nombre.

mro() significa Orden de Resolución de Métodos. Devuelve una lista de los tipos de los que se deriva la clase, en el orden en que se buscan los métodos.

mro () o __mro__ funciona solo en nuevas clases de estilo. En Python 3, funcionan sin problemas. Pero en Python 2 esas clases necesitan heredar de objetos.

Esto quizás muestre el orden de resolución.

 class A(object): def dothis(self): print('I am from A class') class B(A): pass class C(object): def dothis(self): print('I am from C class') class D(B, C): pass d_instance= D() d_instance.dothis() print(D.mro()) 

y la respuesta sería

 I am from A class [, , , , ] 

La regla es la profundidad primero, 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.

Orden de resolución será diferente en la herencia de diamantes.

 class A(object): def dothis(self): print('I am from A class') class B1(A): def dothis(self): print('I am from B1 class') # pass class B2(object): def dothis(self): print('I am from B2 class') # pass class B3(A): def dothis(self): print('I am from B3 class') # Diamond inheritance class D1(B1, B3): pass class D2(B1, B2): pass d1_instance = D1() d1_instance.dothis() # I am from B1 class print(D1.__mro__) # (, , , , ) d2_instance = D2() d2_instance.dothis() # I am from B1 class print(D2.__mro__) # (, , , , )