سؤال

في 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__ هو مجرد tuple من: الفصل، وقاعدةها، قاعدة قاعدة، وما إلى ذلك 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() تقف لطلب قرار الأسلوب. ترجع قائمة الأنواع التي يتم فيها مشتق الفصل، بالترتيب الذي يتم البحث فيه عن طرق.

MRO () أو __mro__ يعمل فقط على دروس نمط جديد. في بيثون 3، يعملون دون أي مشاكل. ولكن في بيثون 2 هذه الفصول تحتاج إلى الوراثة من الأشياء.

هذا ربما يظهر ترتيب القرار.

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 أول ذكر لتلك الفئة من 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'>)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top