Pergunta

No django.utils.functional.py:

for t in type(res).mro():  # <----- this
    if t in self.__dispatch:
        return self.__dispatch[t][funcname](res, *args, **kw)

Eu não entendo mro().O que ele faz e o que faz "mro" significa?

Foi útil?

Solução

Siga junto ...:

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

Enquanto tivermos uma única herança, __mro__ é apenas a tupla de: a classe, sua base, a base de sua base, e assim por diante object (Funciona apenas para aulas de novo estilo, é claro).

Agora com múltiplo herança...:

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

... você também tem a garantia de que, em __mro__, nenhuma aula é duplicada e nenhuma aula vem depois de seus ancestrais, exceto que as aulas que entram primeiro no mesmo nível de herança múltipla (como B e C neste exemplo) estão no __mro__ da esquerda para direita.

Todo atributo que você obtém na instância de uma classe, não apenas métodos, é conceitualmente procurado ao longo do __mro__, então, se mais de uma classe entre os ancestrais define esse nome, isso informa onde o atributo será encontrado - na primeira classe no __mro__ Isso define esse nome.

Outras dicas

mro() representa o Método de Ordem de Resolução.Ele retorna uma lista de tipos de classe é derivada de na ordem em que eles são procurados métodos.

mro() ou __mro__ só funciona no novo estilo de classes.No python 3, eles funcionam sem problemas.Mas em python 2 dessas classes precisa herdar de objetos.

Isso talvez mostrasse a ordem de resolução.

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

e a resposta seria

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

A regra é a profundidade, que neste caso significaria d, b, a, C.

Python normalmente usa um profundidade primeiro Encomende ao pesquisar aulas de herdador, mas quando duas classes herdarem da mesma classe, o Python remove a primeira menção dessa classe do MRO.

A ordem de resolução será diferente na herança de diamante.

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'>)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top