Question

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)

Je ne comprends pas mro(). Que fait-il et qu'est-ce que « MRO » signifie?

Était-ce utile?

La solution

Suivez le long ...:

>>> class A(object): pass
... 
>>> A.__mro__
(<class '__main__.A'>, <type 'object'>)
>>> class B(A): pass
... 
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
>>> class C(A): pass
... 
>>> C.__mro__
(<class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
>>> 

Tant que nous avons l'héritage unique, __mro__ est juste le tuple: la classe, sa base, la base de sa base, et ainsi de suite jusqu'à object (ne fonctionne que pour les classes de nouveau style bien sûr)

.

, avec plusieurs l'héritage ...:

>>> class D(B, C): pass
... 
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)

... vous obtenez également l'assurance que, dans __mro__, aucune classe est dupliqué, et aucune classe vient après ses ancêtres, sauf que les classes qui entrent d'abord au même niveau d'héritage multiple (comme B et C dans cet exemple ) sont dans la __mro__ gauche à droite.

si plus d'une classe parmi les ancêtres définit ce nom, non seulement des méthodes, est conceptuellement regardé le long de la __mro__, tous les attributs que vous obtenez sur l'instance d'une classe, donc, cela vous indique où se trouve l'attribut - dans la première classe dans le __mro__ qui définit ce nom.

Autres conseils

mro() signifie Méthode ordre de résolution. Il retourne une liste de types de la classe est dérivée de, dans l'ordre où ils sont recherchés pour les méthodes.

MRO () ou __ __ MRO ne fonctionne que sur les nouvelles classes de style. En Python 3, ils travaillent sans aucun problème. Mais en python 2 ces classes doivent hériter d'objets.

Cela montre peut-être l'ordre de la résolution.

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())

et la réponse serait

I am from A class
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]

La règle est en profondeur d'abord, dans ce cas signifierait D, B, A, C.

Python utilise normalement un -première profondeur pour les classes héritant lors de la recherche, mais quand deux classes héritent de la même classe, Python supprime la première mention de cette classe de MRO.

Ordre de résolution sera différent dans l'héritage de diamant.

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__)
# (<class '__main__.D1'>, <class '__main__.B1'>, <class '__main__.B3'>, <class '__main__.A'>, <class 'object'>)


d2_instance = D2()
d2_instance.dothis()
# I am from B1 class
print(D2.__mro__)
# (<class '__main__.D2'>, <class '__main__.B1'>, <class '__main__.A'>, <class '__main__.B2'>, <class 'object'>)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top