Domanda

In django.utils.functional.py:

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

Non capisco mro(). Che cosa fa e che cosa "MRO" significa?

È stato utile?

Soluzione

Proseguire lungo ...:

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

Fino a quando abbiamo ereditarietà singola, __mro__ è solo la tupla di: la classe, la sua base, la base di sua base, e così via fino a object (funziona solo per classi di nuovo stile ovviamente)

.

Ora, con più eredità ...:

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

... si ottiene anche l'assicurazione che, in __mro__, nessuna classe viene duplicato, e nessuna classe arriva dopo che i suoi antenati, fermo restando che le classi che prima di entrare allo stesso livello di ereditarietà multipla (come B e C in questo esempio ) sono in __mro__ da sinistra a destra.

tutti gli attributi si ottiene su istanza di una classe, non solo i metodi, è concettualmente alzò lo sguardo lungo la __mro__, quindi, se più di una classe tra gli antenati definisce quel nome, questo ti dice dove si troverà l'attributo - in la prima classe nel __mro__ che definisce quel nome.

Altri suggerimenti

mro() sta per metodo di risoluzione Ordine. Esso restituisce un elenco dei tipi della classe è derivata da, nell'ordine in cui vengono ricercati i metodi.

MRO () o __ MRO __ funziona solo su nuove classi di stile. In Python 3, funzionano senza problemi. Ma in Python 2 le classi devono ereditare da oggetti.

Questo sarebbe forse mostrare l'ordine di risoluzione.

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 la risposta sarebbe

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

La regola è in profondità, che in questo caso significherebbe D, B, A, C.

Python usa normalmente un in profondità ordine durante la ricerca classi che ereditano, ma quando due classi ereditano dalla stessa classe, Python rimuove la prima menzione di quella classe da MRO.

Ordine di risoluzione sarà diverso in eredità 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'>)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top