Super, kwargs ומה שביניהן

ניקח כדוגמה את מחלקת Instrumental שירשה ממחלקת Song במחברת הראשונה:

class Instrumental(Song):
    def __init__(self, name, artists=None):
        super().__init__(name=name, lyrics="", artists=artists)

במקרה הזה, השתמשנו ב-super כדי להשתמש באותה פעולת אתחול של Song, בשינוי קל שבו lyrics מוגדר כריק.

איך זה עובד כשיש לנו kwargs? נגיד בדוגמה עם החיות ממחברת 2 - נניח שמחלקת Animal משרתת חנות חיות, ויש לכל חיה גם מאפיין של מחיר:

class Animal(ABC):
    @abstractmethod
    def __init__(self, name, gender, price):
        self.name = name
        self.gender = gender
        self.price = price

אם אני רוצה שאחת החיות תהיה מיוחדת והמחיר שלה יקבע לפי המין שלה (בואו נתעלם מכל מה שרע מוסרית בדוגמה הזו כרגע), האם כך זה אמור להיראות?

class Dog(Animal):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.price = self.get_price()

האם מה שקורה פה זה שא) נדרסת פונקציית האתחול של Animal ב) פונקציית האתחול של Dog משתמשת בפונקציית האתחול שאותה היא דרסה “כלשונה” באמצעות super, ג) בשורה לאחר מכן המשתנה של המחיר נדרס ע"י קביעה שלו באמצעות הפונקציה ששייכת ל-Dog ד) כל הטוב הזה עובר למחלקת העל באמצעות ה-kwargs שב- def init? או שהעברת המשתנים לפונקציית העל בכלל מתבצעת ב-super?

(מתנצלת על החפירה, התלהבות יתר מהטריק שנתן @aviadamar וגיליתי רק עכשיו)

2 לייקים

עד כאן כן

כאן לא: לא קורה פה שום קסם מיוחד, ו־self.price = self.get_price() מתבצעת רק אחרי הקריאה ל־super().__init__(**kwargs) (בסדר שציינת בסעיפים א–ג). ממליץ להתחדד על מה אומר **kwargs

2 לייקים

מבחינת קוד, אין באמת בעיה בדריסה שבשורה של self.price נכון.?
זאת אומרת ככה מצופה מאיתנו לשנות את המשתנים הללו לא?

יש לי שאלה לגבי ההבדלים בין הדוגמאות כאן,
למה במחלקת Instrumental בפעולת האתחול super, צוינו שמות הארגומנטים והפרמטרים
ואילו במחלקת Dog לא?
שאלה נוספת, האם אפשר להגדיר מחלקה אבסטרקטית גם כמחלקה יורשת(במקרה של mixin)?

יאפ

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

 class Instrumental(Song):
    def __init__(self, artists=None, **kwargs):
        super().__init__(lyrics="", artists=artists, **kwargs)

עדיין סיפקתי פה את ה־lyrics הריק שאני רוצה, ודאגתי ש־artists ישאר עם ערך ברירת מחדל None

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

לייק 1

למעשה בsuper נזין רק את הפרמטרים שאנחנו רוצים לעשות בהם שינויים?

בד"כ נהוג להעביר באופן מפורש רק את הפרמטרים שרוצים לשנות, ובשאר לתת ל־**kwargs לטפל

לייק 1