logo

סדר רזולוציית שיטה ב-Python

במדריך זה, נלמד על סדר רזולוציית השיטה, הידוע גם בשם MRO. זהו מושג חיוני של תורשת Python.

סדר פתרון השיטה מתאר את נתיב החיפוש של המחלקה אשר פִּיתוֹן משתמש כדי לקבל את השיטה המתאימה במחלקות המכילות את הרב-הירושה.

מבוא

כפי שאנו יודעים זאת, מחלקה שעוברת בירושה נקראת תת-מחלקה או מחלקה אב, בעוד שהכיתה שיורשת ידועה ככיתה ילדה או תת-מחלקה. ב-multi-heritance, מחלקה יכולה להיות מורכבת מפונקציות רבות, ולכן טכניקת הסדר של פתרון השיטה משמשת לחיפוש בסדר שבו מבוצעת מחלקת הבסיס.

במילים פשוטות - 'המתודה או התכונות נחקרות במחלקה הנוכחית, אם השיטה אינה קיימת במחלקה הנוכחית, החיפוש עובר למחלקות האב וכן הלאה'. זוהי דוגמה לחיפוש עומק-ראשון.

הוא ממלא תפקיד חיוני בירושה מרובה כאשר אותה שיטה ניתן למצוא במחלקות העל המרובות.

להוסיף מחרוזת

כדי להבין את זה בצורה טובה יותר, בואו נראה איך אנחנו יכולים להשתמש בו.

דוגמא -

 class A: def myname(self): print('I am a class A') class B(A): def myname(self): print('I am a class B') class C(A): def myname(self): print('I am a class C') c = C() print(c.myname()) 

תְפוּקָה:

 I am a class C 

הסבר -

יש ירושה מרובה בקוד לעיל. הגדרנו שלוש מחלקות שנקראות A, B ו-C, ולמחלקות הללו יש את אותה שם שיטה שנקראת השם שלי(). יצרנו מחלקה C של אובייקט. האובייקט הפעיל את המחלקה C, לא את המחלקה, בעוד מחלקה C ירש את המתודה מחלקה A.

הסדר מתבצע בקוד לעיל הוא מחלקה ב' - > מחלקה א'. טכניקה זו ידועה בשם MRO (סדר פתרון שיטה).

בואו נבין דוגמה נוספת של ירושה מרובה.

דוגמא -

 class A: def myname(self): print(' I am a class A') class B(A): def myname(self): print(' I am a class B') class C(A): def myname(self): print('I am a class C') # classes ordering class D(B, C): pass d = D() d.myname() 

תְפוּקָה:

 I am a class B 

הסבר -

בקוד לעיל, יצרנו מחלקה D נוספת מבלי להגדיר תכונות מחלקה שירשו את מחלקות B ו-C. כאשר הפעלנו את השיטה השם שלי(), זה הולך לכיתה D ומחפש את השם שלי( ) פונקציה. אבל לכיתה ד' אין שום הצהרה. לפיכך, החיפוש עובר לכיתה ב', מקבל את השם שלי() פונקציה ומחזירה את התוצאה. החיפוש יתבצע באופן הבא.

 Class D -> Class B -> Class C -> Class A 

אם לכיתה B לא תהיה שיטה, היא תפעיל את שיטת המחלקה C.

כאן, אנו מציעים לך להסיר את שיטת Class B ולבדוק מה קורה. על ידי כך, תקבל מושג כיצד פועלת רזולוציית השיטה.

סדר בסגנון ישן וחדש

בגרסה הישנה של Python (2.1), אנו מוגבלים להשתמש במחלקות הישנות אבל פִּיתוֹן (2.2 והמשך), נוכל להשתמש בשיעורים החדשים. כברירת מחדל, לפייתון 3 יש מחלקות מקוריות (חדשות). ההורה הראשון של מחלקת הסגנון החדשה יורש ממחלקת הבסיס 'אובייקט' של Python. בואו נראה את הדוגמה הבאה -

דוגמא -

 # Old style class class OldStyleClass: pass # New style class class NewStyleClass(object): pass 

סגנון ההצהרה של שתי המעמדות שונה. ברזולוציית השיטה, מחלקות בסגנון ישן עוקבות אחר האלגוריתם של עומק ראשון משמאל לימין (DLR), ואילו מחלקות סגנון חדשות משתמשות באלגוריתם C3 Linearization תוך ביצוע ירושה מרובה.

אלגוריתם DLR

Python יוצר רשימה של מחלקות תוך יישום הירושה המרובה בין המחלקות. הרשימה הזו משמשת כדי לקבוע לאיזו שיטה יש לקרוא אחת מופעלת על ידי מופעים.

אנו יכולים להניח שעובדים לפי שמה שכן רזולוציית השיטה תחפש בעומק תחילה, ולאחר מכן תעבור משמאל לימין. להלן הדוגמה.

דוגמא -

 class A: pass class B: pass class C(A, B): pass class D(B, A): pass class E(C,D): pass 

ראשית, האלגוריתם יחפש במחלקת המופעים את השיטה שהופעלה. אם לא נמצא, זה נכנס להורים הראשונים, אם גם לא נמצא. זה יבדוק את ההורה של ההורה. זה יימשך עד סוף שיעורי הירושה.

בדוגמה שלמעלה, סדר פתרון השיטה יהיה -

 class D -> class B -> class A -> class C -> class A 

אבל, A לא יכול להיות נוכח פעמיים אז -

 class D -> class B -> class A -> class C -> 

אלגוריתם זה מראה את ההתנהגות המוזרה באותה תקופה. בוא נראה את הדוגמה למטה.

דוגמא -

 class A: pass class B: pass class C(A, B): pass class D(B, A): pass class E(C,D): pass 

לפי אלגוריתם DLR, הסדר יהיה E, C, D, B, A. יש את החלפת המחלקות A & B במחלקה C, שהיא מאוד מעורפלת. זה אומר שהאלגוריתם לא שומר על תכונת המונוטוניות.

סמואל פרדוני היה האדם הראשון שגילה חוסר עקביות בין אלגוריתמי ה-MRO.

אלגוריתם ליניאריזציה C3

אלגוריתם ליניאריזציה C3 הוא גרסה טובה יותר של אלגוריתם DLR מכיוון שהוא מסיר את חוסר העקביות. לאלגוריתם זה יש כמה הגבלות המפורטות להלן.

  • ילדים חייבים להקדים את הוריהם.
  • אם מחלקה מסוימת יורשת מהמחלקה האחת או יותר, הן נשמרות בסדר המצוין בטופלה של מחלקת הבסיס.

כללים של אלגוריתם לינאריזציה C3

  • המבנה של סדר פתרון השיטה מוגדר על ידי גרף הירושה.
  • המשתמש חייב לבקר בכיתת העל רק לאחר ביקור בשיטות של הכיתות המקומיות.
  • שמור על מונוטוניות

כיתה לשיטת רזולוציה

פייתון מספקת שתי דרכים לקבל את סדר רזולוציית המתודה של מחלקה - __mro__ תכונה או mro() שיטה. בעזרת שיטות אלו נוכל להציג את סדר השיטה בה הן נפתרות.

בואו נבין את הדוגמה הבאה.

דוגמא -

k אלגוריתם השכן הקרוב
 class A: def myname(self): print(' I am a class A') class B(A): def myname(self): print(' I am a class B') class C(A): def myname(self): print('I am a class C') # classes ordering class D(B, C): pass # it prints the lookup order print(D.__mro__) print(C.mro()) 

תְפוּקָה:

 (, , , , ) [, , ] 

כפי שאנו יכולים לראות בפלט לעיל, אנו מקבלים את סדר סדר רזולוציית השיטה. באופן כזה, אלגוריתם ליניאריזציה C3 פועל להורשה מרובה.