ترتيب استدعاء الدوال (Method Resolution Order)
جزء من قسم Object Oriented Programming في رحلة Python على Coddy — الدرس 21 من 64.
ترتيب حل الطرق (MRO) هو التسلسل الذي يستخدمه Python للبحث عن الطرق عندما تحتوي فئات متعددة على نفس اسم الـ method.
إليك مثالاً يحتوي على فئات متعددة تمتلك نفس الـ method:
class A:
def method(self):
return "Method from A"
class B:
def method(self):
return "Method from B"
class C(A, B):
passتحقق من MRO باستخدام __mro__:
print(C.__mro__)المخرجات:
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)تُعد السمة __mro__ عبارة عن tuple تحتوي على جميع classes في resolution order. العنصر first (__mro__[0]) هو دائماً class نفسه (C)، متبوعاً بـ parent classes من اليسار إلى اليمين (A، ثم B)، وأخيراً built-in object class.
أنشئ كائنًا وادعُ الـ method:
c = C()
print(c.method())Output:
Method from Aعثرت Python على الـ method في الـ class A أولاً (عند الفهرس 1 في الـ MRO)، لذا قامت باستخدامها.
قم بتغيير ترتيب الوراثة لرؤية الفرق:
class D(B, A): # B يأتي قبل A الآن
pass
print(D.__mro__)
d = D()
print(d.method())الناتج:
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
Method from Bالآن يجد Python الـ method الخاص بـ B أولاً لأن B يأتي before A في قائمة الـ inheritance. يمكنك الوصول إلى classes محددة في الـ MRO باستخدام الفهرسة - D.__mro__[0] هو D نفسه، و D.__mro__[1] هو B، و D.__mro__[2] هو A.
يمكنك أيضًا استخدام الدالة mro():
print(C.mro())بينما توفر mro() و __mro__ نفس التسلسل من classes، إلا أنهما تختلفان في النوع: ترجع __mro__ tuple، بينما ترجع mro() list.
نقطة رئيسية: يبحث Python عن الطرق (methods) وفقًا لترتيب MRO - الكلاس نفسه أولاً (الفهرس 0)، ثم الكلاسات الأب من اليسار إلى اليمين كما هي مدرجة في تعريف الكلاس (الفهارس 1، 2، إلخ). يتم استخدام أول طريقة يتم العثور عليها.
التحدي
متوسطفي هذا التحدي، ستعمل على تنفيذ هيكلية صنف (class hierarchy).
ستحتاج إلى تعديل هذه الملفات:
device.py: قم بتنفيذ صنف BaseDevicescreen.py: قم بتنفيذ صنفScreenالذي يرث منDevicecomputer.py: قم بتنفيذ صنفComputerالذي يرث منDevicelaptop.py: قم بتنفيذ صنفLaptopوراثات متعددة (multiple inheritance)driver.py- قم بتنفيذ حالات الاختبار للتأكد من أن التنفيذ الخاص بك يعمل بشكل صحيح
يحتوي كل ملف على تعليقات TODO تفصيلية ستوجهك خطوة بخطوة خلال عملية التنفيذ.
جرّب بنفسك
# TODO: استورد جميع الفئات المطلوبة
# from device import Device
# from screen import Screen
# from computer import Computer
# from laptop import Laptop
def explain_mro(class_name):
# TODO: اطبع الـ MRO (Method Resolution Order) للفئة المعطاة
# TODO: التنسيق: "MRO for [class name]:" (ملاحظة: لا مسافة بعد النقطتين)
# TODO: استخدم class_name.__name__ للحصول على اسم الفئة
# TODO: استخدم class_name.__mro__ للحصول على tuple الـ MRO
# TODO: اطبع اسم كل فئة في الـ MRO على أسطر منفصلة
# TODO: أنشئ مثيلاً من الفئة
# TODO: استدعِ power_on() على المثيل واحفظ النتيجة
# TODO: Print: "Power on result: [result]"
# TODO: اطبع سطرًا فارغًا لتحسين القراءة
pass
# اختبر الكود الخاص بك
# TODO: استدعِ explain_mro() مع كل فئة: Device, Screen, Computer, و Laptop
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
1أساسيات OOP
الملفات الخارجيةمقدمة في OOPClasses مقابل Objectsمعامل selfMethodsAttributesدالة البناء (__init__)مراجعة - آلة حاسبة بسيطة4الوراثة
الوراثة الأساسيةدالة ()superإعادة تعريف الدوال (Method Overriding)الوراثة المتعددةترتيب استدعاء الدوال (Method Resolution Order)مراجعة - هيكلية الموظفين5تعدد الأشكال
مراجعة إعادة تعريف الدوالمفهوم Duck Typingالأصناف والدوال المجردةتصميم الواجهاتملخص - حاسبة الأشكال