ใน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" หมายถึงอะไร?
ใน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__
ก็เป็นเพียงทูเพิลของคลาสฐานของมันฐานของฐานและอื่น ๆ จนถึงobject
(ใช้ได้กับคลาสสไตล์ใหม่เท่านั้น)
ตอนนี้มีหลายมรดก ... :
>>> 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
สามารถกำหนดได้โดย metaclass ที่เรียกว่าครั้งหนึ่งที่เริ่มต้นเรียนและผลที่ได้จะถูกเก็บไว้ใน__mro__
- ดูdocs.python.org/library/...
mro()
ย่อมาจาก Method Resolution Order ส่งคืนรายการประเภทที่คลาสได้มาตามลำดับที่ค้นหาเมธอด
mro ()หรือ__mro__ ใช้งานได้กับคลาสรูปแบบใหม่เท่านั้น ใน python 3 ทำงานได้โดยไม่มีปัญหาใด ๆ แต่ใน python 2 คลาสเหล่านั้นจำเป็นต้องสืบทอดจากobject
.
นี่อาจจะแสดงลำดับความละเอียด
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())
และการตอบสนองจะเป็น
I am from A class
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]
กฎคือความลึกก่อนซึ่งในกรณีนี้จะหมายถึง D, B, A, C
โดยปกติ Python จะใช้ลำดับความลึกเป็นอันดับแรกเมื่อค้นหาคลาสที่สืบทอดมา แต่เมื่อสองคลาสสืบทอดมาจากคลาสเดียวกัน Python จะลบการกล่าวถึงครั้งแรกของคลาสนั้นออกจาก mro
ลำดับความละเอียดจะแตกต่างกันในการสืบทอดเพชร
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'>)
class B3
แต่ในกรณีที่สองมันเป็นclass A
หลังจากนั้นclass B1