اذهب إلى المحتوى
  • 0

ما هو إستخدام super في بايثون؟

Adam Ebrahim

السؤال

مرحبًا

أحاول فهم كيفية استخدام الدالة super()، عندما قمت بعمل صنفين classes واحد بداخله دالة super والآخر بدونها لم أجد أي فرق على الإطلاق.

ما هو إستخدام super وهل لها قيمة معينة؟ ما التغيرات التي تحدث للصنف عند إستعمالها؟

رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 1

استخدامك للدالة super بداخل الصنف الابن يمنحك الوصول إلى الميثود في الصنف الأب ونستخدمها أيضا في الوراثة المتعددة, لنحاول شرح ذلك بمثال

class Animal(object):
  def __init__(self, Name):
    print(Name)
    
class Dog(Animal):
  def __init__(self):
    print('الكلب له اربعة أرجل.')
    super().__init__('الكلب')
    
d1 = Dog()

كما تلاحظ قمت بانشاء صنفين, الصنف الاب Animal والصنف الابن Dog, لاحظ في constructor الابن قمت باستدعاء دالة ال constructor الخاصة بالصنف الأب وذلك باستخدام الدالة super() 
هكذا يمكننا الاستفادة من الدالة super()

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

 

تعيد الدالة super()‎ كائنا وسيطا يفوض استدعاءات التوابع إلى صنف أب أو صنف شقيق للصنف الذي استدعيت منه الدالة.

هذا مفيد للوصول إلى التوابع الموروثة التي أعيدت كتابتها في صنف معيّن. ترتيب البحث يكون هو نفسه التّرتيب المستخدم من طرف الدالة getattr()‎ لكن النوع type‎ المعطى يتجاهل.

المعاملات:

type: النوع الذي ستقوم الدّالة super()‎ بتفويض استدعاءات التّوابع إلى صنف أب أو صنف شقيق له.

تعرض الخاصية __mro__ الخاصة بالصّنف type ترتيب البحث عن التوابع (method resolution search order) الذي يستعمل من طرف كلّ من الدّالة getattr‎()‎ والدّالة super()‎ . وتكون الخاصيّة ديناميكيّةً يُمكن لها أن تتغيّر كلّمَا حُدّثت شجرة الوراثة (inheritance hierarchy).

object-or-type:إن لم تُمرّر قيمة للمُعامل، فالكائن super‎ المُعاد لا يكون مربوطًا (unbound). إن كانت قيمة المُعامل كائنًا، فيجب على الاستدعاء ‎isinstance‎(‎obj‎,‎ type‎)‎‎ أن يُعيد القيمة True‎. إن كانت قيمة المُعامل نوعًا (type)، فيجب على الاستدعاء ‎issubclass‎(‎type2‎,‎ type‎)‎‎ أن يُعيد القيمة True‎ (وهذا مُفيد لتوابع الأصناف).

القيمة المعادة:

كائن وسيط يُفوّض استدعاءات التّوابع إلى صنف أبٍ أو صنف شقيق للصّنف الذي استُدعيَت منه الدّالة.

أمثلة:

هناك حالتان تستعمل فيهما الدّالة super()‎ عادة:

تستعمل للوصول إلى الصّنف الأب في شجرة أصناف ذات وراثة وحيدة (class hierarchy with single inheritance) دون الحاجة إلى تسمية الصنف مباشرة، ما يسمح للشيفرة بأن تكون قابلة للتّطوير والصيانة بشكل أفضل، وحالة الاستخدام هذه تشابه طريقة استخدام super()‎ في لغات البرمجة الأخرى.

المثال التّالي يُوضّح حالة الاستخدام هذه:

class A:
    def add(self, x, y): # دالّة تُعيد مجموع عددين
         return x+y
     
class B(A): # وراثة من الصّنف الأب
     def add_print(self, x, y): # دالّة تُضيف العددين وتطبع العمليّة
         result = super().add(x, y) # استدعاء تابع يتواجد في الصّنف الأب دون تسميّة الصّنف الأب صراحةً
         print(f'{x}+{y}={result}') # طباعة العمليّة الحسابيّة
         
adder = B() # إنشاء كائن من الصّنف الوارث
adder.add_print(1, 2) # استدعاء دالّة الإضافة والطّباعة
#1+2=3
adder.add_print(1, 5)
#1+5=6

الحالة الثانيّة التي تستخدم فيها هي عند الرغبة في استعمال وراثة متعددة متعاونة (cooperative multiple inheritance) في بيئة تنفيذ ديناميكية (أي أن الصنف يمكن له أن يرث من أكثر من صنف واحد). هذه الميزة موجودة فقط في لغة بايثون ولا توجد في لغات البرمجة المجمعة (statically compiled languages) أو في لغات البرمجة التي لا تدعم سوى الوراثة الأحادية (أي أن الصنف لا يُمكن أن يرث إلا من صنف واحد فقط). ما يمكن من تطبيق "تخطيطات الماسة (diamond diagrams)" عندما تحتوي أصناف آباء عدة على نفس التابع. يجب على هذا التابع أن يمتلك نفس توقيع الاستدعاء (calling signature) في جميع الحالات (لأنّ ترتيب الاستدعاءات يحدد في وقت التّنفيذ runtime، ولأن الترتيب يتغير حسب تغيّر شجرة الأصناف، ولأن الترتيب يمكن له أن يشمل أصنافا شقيقة غير معلومة قبل بدء وقت التنفيذ).

class C(B):
    def method(self, arg):
        super().method(arg)    # هذا الاستدعاء مُكافئ للاستدعاء أدناه
                               # super(C, self).method(arg)

ملاحظات:

الدالة super()‎ مطبقَة كجزء من عملية الرّبط للبحث عن الخاصيات بوضوح (explicit) باستخدام النّقطة .‎ مثل ‎super‎(‎)‎.‎_‎_‎getitem‎_‎_‎(‎name‎)‎. وتقوم بذلك عبر تطبيق تابع ‎_‎_‎getattribute‎_‎_‎(‎)‎ خاص بها للبحث عن الأصناف بترتيب يمكن توقّعه يَدعم الوراثة المتعددة المتعاونة. وبالتّالي، فالدالة super‎()‎ غير معرفَة للبحث الضمني (implicit) باستخدام الجمل أو العوامل مثل super‎()‎‎[‎name‎]‎.

استخدام super‎()‎ ليس محصورا داخل التّوابع فقط، المعاملان اللذان تقبلهما الدالة يحددان المراجع المناسبة التي ستنشأ. استدعاء الدالة دون عوامل يعمل داخل الأصناف فقط، لأن المجمع يملأ الفراغات المطلوبة للحصول على الصنف المناسب، إضافة للوصول إلى النسخة الحالية للتوابع العادية.

 

# تم تعديله

تم التعديل في بواسطة Ali Haidar Ahmad
رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...