Was bedeutet „MRO ()“ tun?
-
18-09-2019 - |
Frage
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)
Ich verstehe nicht mro()
. Was ist zu tun und was bedeutet „MRO“ bedeuten?
Lösung
Folgen Sie entlang ...:
>>> 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'>)
>>>
Solange wir einzelnes Erbe haben, __mro__
ist nur die Tupel aus: die Klasse, seine Basis, Basis seiner Basis ist und bis so weiter object
(funktioniert nur für neuen Stil Klassen natürlich)
Jetzt, mit mehrere Vererbung ...:
>>> class D(B, C): pass
...
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
... Sie erhalten auch die Gewissheit, dass, in __mro__
wird keine Klasse dupliziert, und keine Klasse kommt nach seinen Vorfahren, Klassen speichern, dass die zuerst auf dem gleichen Niveau der Mehrfachvererbung (wie B und C in diesem Beispiel geben ) sind in den __mro__
links nach rechts.
Jedes Attribut, das Sie auf einer Klasse Instanz erhalten, nicht nur Methoden, ist konzeptionell entlang der __mro__
aufblickte, so, wenn mehr als eine Klasse unter den Vorfahren definiert, dass Name, das sagt Ihnen, wo das Attribut gefunden wird - in die erste Klasse in der __mro__
, die diesen Namen definiert.
Andere Tipps
mro()
steht für Methode Auflösung bestellen. Es gibt eine Liste von Typen der Klasse von abgeleitet wird, in der Reihenfolge ihrer Methoden gesucht werden.
MRO () oder __ __ MRO funktioniert nur bei Klassen neuen Stils. In Python 3, funktionieren sie ohne Probleme. Aber in Python 2 müssen diese Klassen von Objekten erben.
Das würde vielleicht zeigt die Reihenfolge der Auflösung.
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())
und Antwort wäre
I am from A class
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]
Die Regel ist, zuerst in der Tiefe, die in diesem Fall würde bedeuten, D, B, A, C.
Python normalerweise verwendet ein depth-first , um, wenn Vererbungsklassen sucht, aber wenn zwei Klassen aus der gleichen Klasse erben, entfernt Python die erste Erwähnung dieser Klasse von MRO.
Reihenfolge der Auflösung wird in Diamanten Vererbung unterschiedlich sein.
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'>)