تكرار السؤال: …
الإجابة المختصرة
يحدد MRO (المحسوب بخوارزمية C3) ترتيب البحث عن الدوال عبر الـ classes، و super() لا تستدعي الأب المباشر بالضرورة بل الـ class التالي في MRO للكائن الفعلي.
الشرح
يمكن رؤية الترتيب عبر ClassName.__mro__. في الوراثة على شكل ماسة (diamond) يضمن C3 أن كل class يظهر مرة واحدة وبعد كل أبنائه. لكي تعمل الوراثة التعاونية يجب أن يستدعي كل class الدالة super() ويقبل **kwargs ويمرر ما لا يخصه. استخدم الـ mixins الصغيرة ذات المسؤولية الواحدة، وتجنب الوراثة المتعددة لمجرد إعادة استخدام الكود حين يكون التركيب (composition) أوضح.
مثال بالكود
class Base:
def save(self):
print("Base")
class Logged(Base):
def save(self):
print("Logged")
super().save()
class Validated(Base):
def save(self):
print("Validated")
super().save()
class Model(Logged, Validated):
pass
Model().save() # Logged → Validated → Base
print([c.__name__ for c in Model.__mro__])أخطاء شائعة
- استدعاء Parent.method(self) مباشرة في وراثة متعددة مما يتسبب في تنفيذ الـ Base مرتين.
- افتراض أن super() تشير دائمًا إلى الأب المكتوب في تعريف الـ class.