דילוג לתוכן המרכזי
מודול 7 · שיעור 3 מתוך 427/36 בקורס~12 min
שיעורי מודול (3/4)

שיטות מיוחדות (דנדר)

שיטות מיוחדות (נקראות שיטות דנדר כי הן מתחילות ונגמרות עם קו תחתון כפול: __name__) הם הווים שמאפשרים לחפצים שלך שילוב עם השפה: ייצוג טקסט, השוואה עם ==, תמיכה ב-len(), in, אופרטורים וכו'.

כבר השתמשת באחד: __init__.

__str__ ו__repr__

הם שולטים במה שמופיע עם print() וב-REPL.

Python
class Punto:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Punto({self.x}, {self.y})"

    def __str__(self):
        return f"({self.x}, {self.y})"

p = Punto(3, 4)
str(p)        # '(3, 4)'        — per umani
repr(p)       # 'Punto(3, 4)'   — per debugger / dev
print(p)      # '(3, 4)'
p             # Punto(3, 4)     in REPL → repr
[p, p]        # [Punto(3, 4), Punto(3, 4)]   — sempre repr nei contenitori

אם אתה מגדיר רק __repr__, Python משתמש בו גם כחלופה עבור __str__.

__eq__: הגדרה מחדש של ==

כברירת מחדל a == b משווה את המזהים של האובייקטים (is), לא התוכן שלהם. להשוואה מבנית, הגדר את __eq__:

Python
class Punto:
    def __init__(self, x, y):
        self.x, self.y = x, y

    def __eq__(self, other):
        if not isinstance(other, Punto):
            return NotImplemented
        return (self.x, self.y) == (other.x, other.y)

Punto(1, 2) == Punto(1, 2)    # True
Punto(1, 2) == Punto(3, 4)    # False

החזרת NotImplemented (מילת מפתח מיוחדת, לא False!) כאשר הסוגים אינם ניתנים להשוואה הוא התרגול הנכון: Python ינסה לאחר מכן עם __eq__ של אופרנד אחר.

__len__: תמיכה ב-len()

Python
class Cesto:
    def __init__(self):
        self.frutti = []

    def __len__(self):
        return len(self.frutti)

c = Cesto()
c.frutti.append("mela")
len(c)        # 1
bool(c)       # True (len > 0)

על ידי הגדרת __len__, אתה גם מקבל את הבוליאני בחינם: אובייקט עם len() == 0 הופך להיות מזויף.

דאנדרים שימושיים אחרים (סקירה כללית)

  • __add__(self, other) → מגדיר מחדש את +
  • __lt__, __le__, __gt__, __ge__ → אופרטורים להשוואה
  • __contains__(self, item) → תומך ב-item in self
  • __iter__ + __next__ → הופך את האובייקט לחזרה
  • __getitem__(self, key) → תומך ב-self[key]
  • __hash__ ← נדרש להיות מפתח dict/set

התור שלך

פעילות גופנית#python.m7.l3.e1
ניסיונות: 0טוען...

הגדר `כסף` עם __init__(עצמי, סכום, מטבע) ו-__str__ שמחזיר `f'{amount} {currency}'`. צור `s = Money(42, 'EUR')` והעריך `str(s)`.

טוען עורך...
הצג רמז

מחרוזת f ב-__str__.

הפתרון זמין לאחר 3 ניסיונות

סקירת התרגיל

פעילות גופנית#python.m7.l3.e2
ניסיונות: 0טוען...

הגדר 'זוג' עם __init__(עצמי, a, b) ו__eq__ בהתבסס על ההשוואה המבנית של (a, b). הערך את `Pair(1, 2) == Pair(1,2)`.

טוען עורך...
הצג רמז

השווה את הטפולים (self.a, self.b) == (אחר.א, אחר.ב).

הפתרון זמין לאחר 3 ניסיונות

אתגר נוסף

פעילות גופנית#python.m7.l3.e3
ניסיונות: 0טוען...

הגדר מחלקה \`ספר\` עם בנאי שלוקח \`כותרת\` ו\`מחבר\`. הגדר את השיטה המיוחדת \`__str__(self)\` כך שהיא תחזיר את המחרוזת \`"כותרת לפי מחבר"\` (למשל \`'1984 מאת ג'ורג' אורוול'\`). הצג ספר והעריך את \`str(book)\`.

טוען עורך...
הצג רמז

השתמש ב-f"{self.title} מאת {self.author}" בתוך def __str__(self):.

הפתרון זמין לאחר 3 ניסיונות