סדר פתרון המתודות
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Python של Coddy. שיעור 21 מתוך 64.
סדר פתרון המתודות (MRO) הוא הרצף שבו Python מחפשת מתודות כאשר לכמה מחלקות יש שם מתודה זהה.
הנה דוגמה עם כמה מחלקות שיש להן אותה מתודה:
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 שמכיל את כל המחלקות לפי סדר הפתרון. האיבר הראשון (__mro__[0]) הוא תמיד המחלקה עצמה (C), ואחריו מחלקות האב משמאל לימין (A, ואז B), ולבסוף המחלקה המובנית object.
צרו אובייקט וקראו למתודה:
c = C()
print(c.method())פלט:
Method from APython מצאה את המתודה במחלקה 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 מוצאת תחילה את המתודה של B כי B מופיעה לפני A ברשימת ההורשה. אפשר לגשת למחלקות ספציפיות ב-MRO באמצעות אינדוקס - D.__mro__[0] היא D עצמה, D.__mro__[1] היא B, ו-D.__mro__[2] היא A.
אפשר גם להשתמש בשיטה mro():
print(C.mro())אף ש־mro() ו־__mro__ מספקים את אותה רצף מחלקות, הם שונים בסוג: __mro__ מחזיר tuple, ואילו mro() מחזיר list.
נקודה חשובה: Python מחפשת מתודות לפי סדר MRO — תחילה במחלקה עצמה (אינדקס 0), ולאחר מכן במחלקות האב משמאל לימין, כפי שהן מופיעות בהגדרת המחלקה (אינדקסים 1, 2 וכן הלאה). במתודה הראשונה שנמצאת נעשה שימוש.
אתגר
בינוניבאתגר הזה תממשו היררכיית מחלקות.
יהיה עליכם לערוך את הקבצים האלה:
device.py: ממשו את מחלקת הבסיסDevicescreen.py: ממשו את המחלקהScreenשיורשת מ־Devicecomputer.py: ממשו את המחלקהComputerשיורשת מ־Devicelaptop.py: ממשו את המחלקהLaptopעם ירושה מרובה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 (סדר חיפוש המתודות) של המחלקה הנתונה
# TODO: פורמט: "MRO for [class name]:" (הערה: אין רווח אחרי הנקודתיים)
# TODO: יש להשתמש ב־class_name.__name__ כדי לקבל את שם המחלקה
# TODO: יש להשתמש ב־class_name.__mro__ כדי לקבל את הטופל של ה־MRO
# TODO: יש להדפיס כל שם מחלקה ב־MRO בשורה נפרדת
# TODO: יש ליצור מופע של המחלקה
# TODO: יש לקרוא ל־power_on() על המופע ולשמור את התוצאה
# TODO: הדפיסו: "Power on result: [result]"
# TODO: הדפיסו שורה ריקה לשיפור הקריאות
pass
# בדקו את הקוד שלכם
# TODO: קראו ל-explain_mro() עם כל אחת מהמחלקות: Device, Screen, Computer ו-Laptop
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים (OOP)
קבצים חיצונייםמבוא ל-OOPמחלקות לעומת אובייקטיםהפרמטר selfמתודותמאפייניםשיטת הבנאי (__init__)חזרה: מחשבון פשוט5פולימורפיזם
בחינה מחדש של דריסת מתודותטיפוסיות ברווזמחלקות ומתודות אבסטרקטיותעיצוב ממשקיםסיכום – מחשבון צורות8מושגים מתקדמים בתכנות מונחה עצמים
קומפוזיציה לעומת הורשהMixinsמתודות סטטיות ומתודות מחלקהדקורטורים למחלקותמנהלי הקשרתרגלו בעצמכם: קומפיילר Python אונליין