מירי
כיתה יא · מחלקות ומבני נתונים

מחלקות ועצמים בפייתון תבנית אחת, הרבה עצמים

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

1

הרעיון

class Account:
    def __init__(self, owner, balance):
        self.owner = owner
        self.balance = balance

    def deposit(self, amount):
        self.balance = self.balance + amount

acc = Account("Bakery", 50)
acc.deposit(20)
print(acc.balance)    # 70

class ו-__init__

class מגדיר תבנית. __init__ רץ לבד בכל פעם שיוצרים עצם חדש, ונותן לו ערכים התחלתיים.

self ותכונות

self הוא העצם שעליו עובדים עכשיו. self.balance היא תכונה: משתנה ששייך לעצם, ונשמר כל עוד העצם קיים.

פעולות (מתודות)

פונקציה בתוך מחלקה היא פעולה. ב-acc.deposit(20) פייתון שולחת את acc בתור self, ואת 20 בתור amount.

לזכור: לכל עצם יש תכונות משלו. acc1.balance ו-acc2.balance הם שני משתנים נפרדים, גם אם נבנו מאותה מחלקה.
2

מעבדה: שני חשבונות, מחלקה אחת

בחשבון acc1 יש בהתחלה 50, וב-acc2 יש 20. הזיזו את המחוונים כדי לבחור כמה מפקידים ל-acc1 וכמה מושכים ממנו. לחצו "שורה הבאה" וראו איך התוכנית קופצת לתוך הפעולות. הכרטיסים מראים את התכונות של כל עצם.

נסו את אלה:

הריצו בעצמכם

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

3

טעויות שכולם עושים

שוכחים את self

כל פעולה מקבלת את self כפרמטר ראשון. בלי self, הקריאה acc.deposit(5) נותנת TypeError.

✗ TypeError

def deposit(amount):
    ...

✓ עם self

def deposit(self, amount):
    ...

משתנה מקומי במקום תכונה

בלי self. נוצר משתנה מקומי שנמחק בסוף הפעולה, והתכונה לא משתנה.

✗ לא נשמר

balance = balance + amount

✓ נשמר בעצם

self.balance = self.balance + amount

השמה לא מעתיקה עצם

b = a לא יוצר חשבון חדש. שני השמות מצביעים על אותו עצם, ושינוי דרך אחד נראה דרך השני.

✗ אותו עצם

acc2 = acc1

✓ עצם חדש

acc2 = Account("Club", 50)

מדפיסים עצם בלי __str__

בלי __str__, ההדפסה נראית כמו <__main__.Account object at 0x...>. מגדירים __str__ שמחזיר מחרוזת.

✗ מחזיר מספר

def __str__(self):
    return self.balance

✓ מחזיר מחרוזת

def __str__(self):
    return str(self.balance)
4

דוגמה פתורה: שני רובוטים על קו

כל רובוט מתחיל במקום 0, והפעולה move מזיזה אותו קדימה. יוצרים שני רובוטים ומזיזים כל אחד בנפרד. עקבו אחרי r1.x ו-r2.x.

5

תרגול


  

6

שאלות שכולם שואלים

מה ההבדל בין מחלקה לעצם?

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

למה צריך self בפייתון?

פעולה אחת משרתת את כל העצמים. self אומר לה על איזה עצם היא עובדת עכשיו. כשכותבים acc1.deposit(30), פייתון שולחת את acc1 בתור self, ולכן משתנה acc1.balance ולא acc2.balance.

מה עושה __init__?

__init__ היא פעולה מיוחדת שרצה לבד בכל פעם שיוצרים עצם חדש, למשל Account("Club", 20). בה נותנים לעצם את התכונות ההתחלתיות שלו. תרגלו למטה.