استكشاف طرق بايثون super() و __init__()

Python

الشروع في العمل مع بايثون سوبر ()

غالبًا ما يكون استخدام الدالة super() في برمجة Python الموجهة للكائنات مصدرًا للارتباك للمبتدئين. يتم استخدام هذه الوظيفة القوية في المقام الأول للتأكد من أن أساليب __init__() للفئات الأساسية يتم استدعاؤها بشكل صحيح، مما يسهل بنية تعليمات برمجية أكثر قابلية للصيانة وقابلة للتطوير.

في هذه المقالة، سوف نتعمق في الاختلافات بين استخدام Base.__init__() وsuper().__init__()، ونستكشف سبب كون super() هو النهج المفضل بشكل عام. سنقدم أيضًا أمثلة على التعليمات البرمجية لتوضيح هذه المفاهيم عمليًا.

يأمر وصف
Base.__init__(self) يستدعي مباشرة طريقة __init__ للفئة الأساسية. يُستخدم لضمان تهيئة الفئة الأساسية بشكل صحيح.
super(ChildB, self).__init__() يستدعي الأسلوب __init__ للفئة الأساسية باستخدام الدالة super(). هذه هي الطريقة المفضلة لتهيئة الفئات الأساسية.
print("Base created") طباعة رسالة إلى وحدة التحكم. يُستخدم لتصحيح الأخطاء والتأكد من تهيئة الفئة الأساسية.
print("ChildA created") طباعة رسالة إلى وحدة التحكم. يُستخدم للتأكيد على إنشاء ChildA وتهيئته.
print("ChildB created") طباعة رسالة إلى وحدة التحكم. يُستخدم للتأكيد على إنشاء ChildB وتهيئته.
print("Derived class with Base.__init__") طباعة رسالة تشير إلى أنه تمت تهيئة الفئة المشتقة باستخدام Base.__init__.
print("Derived class with super().__init__") طباعة رسالة تشير إلى أنه تمت تهيئة الفئة المشتقة باستخدام super().__init__.

شرح متعمق لاستخدام Python الفائق ().

توضح البرامج النصية المذكورة أعلاه استخدام و في بايثون لتهيئة الفئات الأساسية ضمن التسلسل الهرمي للفئة. في البرنامج النصي الأول، نحدد فئة أساسية تسمى مع ال __init__() الطريقة التي تطبع "تم إنشاء القاعدة" عند تهيئة مثيل للفئة. ثم نحدد فئتين مشتقتين، و . في ، ال Base.__init__(self) يتم استدعاء الطريقة بشكل صريح داخل نفسها طريقة لضمان تهيئة الفئة الأساسية بشكل صحيح. هذا النهج واضح ومباشر ولكنه قد يكون مرهقًا إذا كان هناك فئات أساسية متعددة أو هياكل وراثة معقدة.

في ، ال يتم استخدام الطريقة بدلا من ذلك. ال تعد الدالة في Python طريقة أكثر مرونة وقابلية للصيانة لاستدعاء أساليب الفئة الأساسية، خاصة في سيناريوهات الوراثة المتعددة. فهو يقوم تلقائيًا بحل الطريقة التي سيتم استدعاؤها بالترتيب الصحيح، باتباع ترتيب دقة الطريقة (MRO). وهذا لا يبسط الكود فحسب، بل يجعله أيضًا أكثر قوة وقدرة على التكيف مع التغييرات في التسلسل الهرمي للفئة. يشرح النص الثاني هذه المفاهيم بشكل أكبر من خلال مقارنة الاستخدام المباشر لـ Base.__init__() و ال وظيفة، مما يدل على كيفية تأثير كل أسلوب على عملية التهيئة.

فهم سوبر بايثون () في وراثة الفصل

بايثون - استخدام super() لاستدعاء الفئة الأساسية __init__()

class Base(object):
    def __init__(self):
        print("Base created")

class ChildA(Base):
    def __init__(self):
        Base.__init__(self)
        print("ChildA created")

class ChildB(Base):
    def __init__(self):
        super(ChildB, self).__init__()
        print("ChildB created")

ChildA()
ChildB()

استكشاف الاختلافات في تهيئة الفئة الأساسية

بايثون - مقارنة Base.__init__() مقابل super().__init__()

class Base:
    def __init__(self):
        print("Base class initialized")

class DerivedWithBaseInit(Base):
    def __init__(self):
        Base.__init__(self)
        print("Derived class with Base.__init__")

class DerivedWithSuperInit(Base):
    def __init__(self):
        super().__init__()
        print("Derived class with super().__init__")

print("Creating DerivedWithBaseInit:")
derived1 = DerivedWithBaseInit()

print("Creating DerivedWithSuperInit:")
derived2 = DerivedWithSuperInit()

الغوص بشكل أعمق في وظيفة بايثون الفائقة ().

بينما ركزت التفسيرات السابقة على الاستخدام الأساسي لـ و ‎من المهم فهم بعض الجوانب المتقدمة وفوائد الاستخدام . إحدى المزايا الرئيسية هي توافقه مع الميراث المتعدد. في التسلسل الهرمي للفئة المعقدة، حيث قد يرث الفصل من فئات أساسية متعددة، باستخدام super() يضمن تهيئة جميع الفئات الأساسية بشكل صحيح وفقًا لترتيب دقة الطريقة (MRO). وهذا يمنع المشكلات المحتملة حيث قد تتم تهيئة الفئة الأساسية عدة مرات أو لا تتم تهيئةها على الإطلاق.

هناك جانب حاسم آخر وهو تحسين إمكانية قراءة التعليمات البرمجية وصيانتها. عند الاستخدام ، يجب على المبرمج تسمية الفئة الأساسية بشكل صريح، مما يجعل التعليمات البرمجية أقل مرونة. إذا تغير اسم الفئة الأساسية أو تطورت بنية الميراث، فسيتم استدعاء كل اتصال مباشر إلى يحتاج إلى تحديث. في المقابل، يلخص اسم الفئة الأساسية، مما يجعل الكود أكثر قابلية للتكيف مع التغييرات. يتوافق هذا التجريد أيضًا مع مبادئ تعدد الأشكال والتغليف، والتي تعتبر أساسية في البرمجة الشيئية.

أسئلة وأجوبة شائعة حول بايثون سوبر ()

  1. ما هو في بايثون؟
  2. هي وظيفة مدمجة تسمح لك باستدعاء الأساليب من فئة الأصل أو الأخوة، مما يضمن التهيئة المناسبة وحل الطريقة في التسلسل الهرمي للميراث.
  3. كيف تختلف عن ؟
  4. يحل ديناميكيًا الطريقة التي سيتم استدعاؤها بناءً على MRO، بينما يستدعي مباشرة طريقة فئة أساسية محددة، وهي أقل مرونة.
  5. لماذا الأفضلية في الميراث المتعدد؟
  6. في الميراث المتعدد يضمن تهيئة جميع الفئات الأساسية بشكل صحيح وفقًا لـ MRO، وتجنب عمليات التهيئة المكررة أو المفقودة.
  7. يستطيع استخدامها خارج ؟
  8. نعم، يمكن استخدامها لاستدعاء أي أسلوب من فئة أحد الوالدين أو الأخوة، وليس فقط .
  9. ما هو ترتيب دقة الطريقة (MRO)؟
  10. MRO هو الترتيب الذي تبحث به بايثون عن الأساليب في التسلسل الهرمي للفئات. يتم تحديده بواسطة خوارزمية الخطية C3.
  11. كيف تنظر إلى MRO للفصل؟
  12. يمكنك عرض MRO باستخدام الطريقة أو يصف.
  13. ماذا يحدث إذا لم تستخدم في فئة مشتقة؟
  14. إذا كنت لا تستخدم ، قد لا تتم تهيئة الفئة الأساسية بشكل صحيح، مما يؤدي إلى حدوث أخطاء محتملة أو سلوك غير متوقع.
  15. هل من الممكن استخدامها في بايثون 2؟
  16. نعم، ولكن بناء الجملة مختلف. في بايثون 2، تستخدم ، بينما في Python 3، يمكنك ببساطة استخدام .

استخدام في Python لا يضمن التهيئة الصحيحة للفئات الأساسية فحسب، بل يعزز أيضًا مرونة التعليمات البرمجية وقابلية الصيانة. إنه مفيد بشكل خاص في سيناريوهات الميراث المتعددة حيث يمكن أن تصبح الاستدعاءات المباشرة لأساليب الفئة الأساسية مرهقة وعرضة للخطأ. من خلال تلخيص أسماء الفئات الأساسية، يسمح لكود أكثر نظافة وأكثر قدرة على التكيف. فهم الفروق الدقيقة في عكس Base.__init__() يعد ضروريًا لكتابة كود Python قوي موجه للكائنات.