التحميل الزائد للعوامل

11.4 التحميل الزائد للعوامل

أهداف التعلم

في نهاية هذا القسم، ينبغي أن تكون قادرًا على:

  • تحديد التوابع السحرية ووصف الغرض منها.
  • تطوير العوامل الحسابية وعوامل المقارنة المُحمَّلة زائدًا للأصناف المعرّفة من قبل المستخدم.

التوابع السحرية والتخصيص

التوابع السحرية (Magic methods) توابع خاصة تنفذ إجراءات للمستخدمين، وعادةً ما تكون مخفية عنهم. تُسمى التوابع السحرية أيضًا توابع دَندَر، لأن هذه التوابع تبدأ وتنتهي بشرطتين سفليتين مزدوجتين (__). مثال: __init__() تابع سحري يُستخدم جنبًا إلى جنب مع __new__() لإنشاء مثيل جديد وتهيئة السمات بسطر بسيط مثل eng = Engineer(). يمكن للمبرمج تعريف تابع سحري بشكل صريح في صنف معرّف من قبل المستخدم لتخصيص سلوك التابع.

نقطة تحقق

تخصيص __str__() في صنف معرّف من قبل المستخدم، Engineer

مفاهيم تطبيقية

التوابع السحرية

1.
أي مما يلي تابع سحري؟
  1. add()
  2. _add_()
  3. __add__()
2.
لماذا التوابع السحرية خاصة؟
  1. لا يمكن استدعاؤها من قبل المستخدم
  2. تنفذ إجراءات داخلية
  3. لها تعريفات ثابتة
3.
بالاستناد إلى المثال أعلاه، حدد التابع (التوابع) السحري (السحرية) في البرنامج المحدّث.
  1. __init__()
  2. __str__()
  3. __init__(), __str__()

التحميل الزائد للعوامل الحسابية

التحميل الزائد للعوامل (Operator overloading) يشير إلى تخصيص وظيفة عامل مُضمَّن. تُحمَّل العوامل الحسابية زائدًا عادةً للسماح بإجراء تغييرات سهلة على مثيلات الأصناف المعرّفة من قبل المستخدم.

نقطة تحقق

التحميل الزائد لـ __add__() لصنف معرّف من قبل المستخدم، Account

العامل الحسابي (العملية) التابع السحري
+ (الجمع)
__add__(self, other)
- (الطرح)
__sub__(self, other)
* (الضرب)
__mul__(self, other)
/ (القسمة)
__truediv__(self, other)
% (باقي القسمة)
__mod__(self, other)
** (الأس)
__pow__(self, other)
جدول 11.1 العوامل الحسابية والتوابع السحرية.

مفاهيم تطبيقية

التحميل الزائد للعوامل الحسابية

4.
مبرمج يعرّف صراحةً عامل باقي القسمة لصنفه المعرّف من قبل المستخدم يُجري ___________ على العامل.
  1. التحميل الزائد
  2. إعادة كتابة
  3. تنفيذ
5.
بالاستناد إلى الشِفرة أدناه، أي وسيط يتطابق مع المُعامِل other في استدعاء Account.__add__()؟
acct_a = Account("Ashe", 6492)
acct_b = Account("Bevins", 5210)

acct_ab = acct_a + acct_b
  1. acct_a
  2. acct_b
  3. acct_ab
6.
أي تعريف لـ __sub__() يُحمِّل العامل - زائدًا لكي تعمل الشِفرة أدناه؟
class Pair:
  def __init__(self, x=0, y=0):
    self.x = x
    self.y = y
  # تعريف __sub__()

p1 = Pair(10, 2)
p2 = Pair(8, 4)
p3 = p1 - p2
print(p3.x, p3.y)
  1.   def __sub__(self):
        return Pair(self.x - other.x, self.y - other.y)
    
  2.   def __sub__(self, other):
        return self.x - other.x, self.y - other.y
    
  3.   def __sub__(self, other):
        return Pair(self.x - other.x, self.y - other.y)
    

التحميل الزائد لعوامل المقارنة

يمكن أيضًا تحميل عوامل المقارنة زائدًا مثل العوامل الحسابية.

عامل المقارنة (العملية) التابع السحري
< (أصغر من)
__lt__(self, other)
> (أكبر من)
__gt__(self, other)
<= (أصغر من أو يساوي)
__le__(self, other)
>= (أكبر من أو يساوي)
__ge__(self, other)
== (يساوي)
__eq__(self, other)
!= (لا يساوي)
__ne__(self, other)
جدول 11.2 عوامل المقارنة والتوابع السحرية.

مثال 11.2

التحميل الزائد لعوامل المقارنة للصنف Account

الشِفرة المُخرَج
class Account:
  def __init__(self, name="", amount=0):
    self.name = name
    self.amount = amount

  def __str__(self):
    return f"{self.name}: ${self.amount}"

  def __lt__(self, other):
    return self.amount < other.amount

  def __gt__(self, other):
    return self.amount > other.amount

  def __eq__(self, other):
    return self.amount == other.amount

acct_a = Account("Ashe", 6492)
acct_b = Account("Bevins", 5210)

print(acct_a < acct_b)
print(acct_a > acct_b)
acct_a.amount = 5210
print(acct_a == acct_b)
False

True

True
جدول 11.3

مفاهيم تطبيقية

التحميل الزائد لعوامل المقارنة

تأمل المثال أعلاه.

7.
كم عدد العوامل التي تم تحميلها زائدًا؟
  1. 3
  2. 4
  3. 5
8.
أي شِفرة تُحمِّل العامل <= زائدًا بشكل مناسب؟
  1.   def __le__(other):
        return self.amount <= other.amount
    
  2.   def __le__(self, other):
        return self.amount <= other.amount
    
  3.   def __le__(self, other):
        return other.amount <= self.amount
    
9.
ما نوع القيمة التي تُرجعها __gt__()؟
  1. مثيل حساب
  2. منطقي
  3. عدد صحيح

جرّب بنفسك

دمج سجلات التمارين

يحتوي الصنف ExerciseLog على سمتين للمثيل: e_type، وهو نوع التمرين، و duration، وهو الوقت المستغرق في التمرين.

حمِّل العامل + زائدًا لدمج سجلين للتمارين (ExerciseLogs) بحيث:

  • إذا كانت أنواع التمارين مختلفة، ادمجها بوضع " and " بينهما. وإلا، استخدم نفس النوع ولا تكرر.
  • اجمع المدد الزمنية معًا.

المدخلات المعطاة:

    walk
    5
    run
    30

المُخرَج هو:

    walk and run: 35 minutes

جرّب بنفسك

توسيع الصنف Account

يسمح استخدام isinstance() للمبرمج بتعريف سلوكيات مختلفة اعتمادًا على نوع الكائن. المُعامِل الأول هو الكائن، والمُعامِل الثاني هو النوع أو الصنف. مثال: isinstance(my_var, int) تُرجع True إذا كان my_var عددًا صحيحًا.

وسّع مثال Account الحالي بحيث يمكن استخدام عامل الجمع أيضًا لإضافة قيمة عدد صحيح إلى سمة amount الخاصة بـ Account.