Sur 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 que signifie "mro" ?
Sur 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 que signifie "mro" ?
Suivez-moi.. :
>>> 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 un seul héritage, __mro__
est juste le tuple de : la classe, sa base, la base de sa base, et ainsi de suite jusqu'à object
(ne fonctionne que pour les classes de type nouveau, bien sûr).
Maintenant, avec multiple 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, en __mro__
aucune classe n'est dupliquée, et aucune classe ne vient après ses ancêtres, sauf que les classes qui entrent pour la première fois au même niveau d'héritage multiple (comme B et C dans cet exemple) sont dans la classe __mro__
de gauche à droite.
Chaque attribut que vous obtenez sur l'instance d'une classe, et pas seulement les méthodes, est conceptuellement recherché le long de l'arbre d'accès de la classe. __mro__
Ainsi, si plus d'une classe parmi les ancêtres définit ce nom, cela vous indique où l'attribut sera trouvé -- dans la première classe de l'arborescence __mro__
qui définit ce nom.
mro
peut être personnalisé par une métaclasse, est appelé une fois lors de l'initialisation de la classe, et le résultat est stocké dans le fichier __mro__
-- voir docs.python.org/library/ .
Pourquoi s'appelle-t-il ordre de résolution des méthodes au lieu de ordre de résolution des attributs ?
mro()
est l'abréviation de Method Resolution Order. Il renvoie une liste de types dont la classe est dérivée, dans l'ordre dans lequel les méthodes sont recherchées.
mro()
y __mro__
ne fonctionnent que sur les nouvelles classes de style. Dans Python 3, ils fonctionnent sans aucun problème. En Python 2, cependant, ces classes doivent hériter de object
.
Cela montrerait peut-être l'ordre de 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 celle de la profondeur d'abord, ce qui dans ce cas signifierait D, B, A, C.
Python utilise normalement un profondeur d'abord lors de la recherche de classes héritantes, mais lorsque deux classes héritent de la même classe, Python supprime la première mention de cette classe dans mro.
L'ordre de résolution sera différent dans l'héritage des diamants.
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'>)
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
5 votes
python.org/download/releases/2.3/mro