В django.utils.functional.py
:
for t in type(res).mro(): # <----- this
if t in self.__dispatch:
return self.__dispatch[t][funcname](res, *args, **kw)
Я не понимаю mro()
. Что это делает и что означает "mro"?
Следуйте за...:
>>> 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'>)
>>>
Пока у нас единое наследование, __mro__
- это всего лишь кортеж: класса, его базы, базы и т.д. до объекта
(разумеется, работает только для классов нового стиля).
Теперь, при множественном наследовании ...:
>>> class D(B, C): pass
...
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
... вы также получаете уверенность, что в __mro__
ни один класс не дублируется, и ни один класс не приходит после своих предков, за исключением тех классов, которые впервые входят на тот же самый уровень множественного наследования (как B и C в этом примере) находятся в __mro__
слева направо.
Каждый атрибут, который вы получаете на экземпляре класса, а не только методы, концептуально просматривается вдоль __mro__
, поэтому, если более одного класса среди предков определяет это имя, это говорит вам, где будет найден атрибут -- в первом классе в __mro__
, который определяет это имя.
mro()
означает порядок разрешения методов. Возвращает список типов, из которых выведен класс, в порядке их поиска методов.
mro() или __mro__ работает только с новыми классами стилей. На питоне 3 они работают без проблем. Но на питоне 2 эти классы должны наследовать от объектов.
.