• בלוג
  • עמוד 52
  • השנה 2023. הגיע הזמן להפסיק לדבר על ירושה בפייתון

השנה 2023. הגיע הזמן להפסיק לדבר על ירושה בפייתון

31/07/2023

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

אני מבין את ההגיון הזה ב Java. אבל בפייתון? הנה הקוד למחלקה של עגלת קניות שמכילה 3 סוגים של מוצרים:

from dataclasses import dataclass

class Cart:
  def __init__(self):
    self.products = []

@dataclass
class Table:
  price: float
  name: str

@dataclass
class Shoes:
  price: float
  color: str

c = Cart()
c.products.append(Table(price=120, name="Big Table"))
c.products.append(Table(price=80, name="Small Table"))
c.products.append(Shoes(price=180, color="orange"))

יותר מזה, אני יכול להוסיף פונקציה ל Cart שתדפיס את המחיר הכולל של המוצרים:

class Cart:
  def __init__(self):
    self.products = []

  def price(self):
    return sum(p.price for p in self.products)

ואפשר להגדיר פרוטוקול כדי לבדוק טיפוסים בזמן כתיבת הקוד:

class Product(Protocol):
  price: float

class Cart:
  def __init__(self) -> None:
    self.products: list[Product] = []

  def price(self):
    return sum(p.price for p in self.products)

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

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

השנה 2023 וכבר מזמן אין סיבה להשתמש בירושה ב Python.