פייתון/פייתון גרסה 2/מחלקות


פרק זה לוקה בחסר. אתם מוזמנים לתרום לוויקיספר ולהשלים אותו. ראו פירוט בדף השיחה.



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

הצורך במחלקות

עריכה

עד כה השתמשנו בהשמות כגון:

>>> a=3; type(a)
<type 'int'>
>>> b=3.0; type(b)
<type 'float'>
>>> c=[3,0]; type(c)
<type 'list'>

הגדרת מחלקה - הקדמה

עריכה
class student:
    pass
   מגדירים מחלקה בעזרת המילה השמורה class
def make_student(id):
    s = student()
    
    s.id = id
    s.grades = {}

    return s;


def update_student_grade(s, subject, grade):
    s.grades[subject] = grade


def failing_student(s):
    return len( [(s, g) for (s, g) in s.grades.iteritems() if g < 60] ) > 0

הגדרת מחלקה

עריכה
class student:
    def __init__(self, id):
        self._id = id
        self._grades = {}
s = student('233445598')
class student:
    def __init__(self, id):
        self._id = id
        self._grades = {}

    def update_grade(self, subject, grade):
        self._grades[subject] = grade


class student:
    def __init__(self, id):
        self._id = id
        self._grades = {}

    def update_grade(self, subject, grade):
        self._grades[subject] = grade

    def failing(self):
        return len( [(s, g) for (s, g) in self._grades.iteritems() if g < 60] ) > 0
s = student('233445598')

s.update_grade('heshbon', 80)
s.update_grade('handasa', 49)

עוד דוגמה

עריכה

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

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

# Main:
p=Point(3.0,4.0)
print p.x,p.y

מבחינת מתכנת שמשתמש במחלקה Point, כל שעליו לעשות הוא להצהיר על משתנה מסוים כ-"Point", ולהעביר ערכים התחלתיים (לא חייבים - אפשר לאתחל מאוחר יותר).

מבחינת המחלקה, עלינו להגדיר פונקציה מיוחדת, הנקראת __init__ ובתוכה לכתוב את כל פעולות האתחול שברצוננו לבצע ברגע שבו המתכנת מצהיר על משתנה כ-Point. פונקציה מיוחדת זו נקראת פונקציה בונה (constructor).

על מנת ליצור משתנים "פנימיים", חייבים להשתמש במילה השמורה "self".

כעת נרצה להשתמש במחלקה Point כדי להגדיר את האוביקטים "ישר" ו"משולש":

class Line:
    def __init__(self,p1,p2):
        self.p1=p1
        self.p2=p2
    
    def Length(self):
        return sqrt((self.p1.x-self.p2.x)**2 + (self.p1.y-self.p2.y)**2)

class Triangle:
    def __init__(self,p1,p2,p3):
        self.p1=p1
        self.p2=p2
        self.p3=p3
        l1 = Line(self.p1,self.p2)
        l2 = Line(self.p2,self.p3)
        l3 = Line(self.p3,self.p1)
        self.a = l1.Length()
        self.b = l2.Length()
        self.c = l3.Length()
        
    def Perimeter(self):
        return self.a+self.b+self.c

    def Area(self):
        p = 0.5*self.Perimeter()    # Semiperimeter
        # Heron's formula:
        return sqrt(p*(p-self.a)*(p-self.b)*(p-self.c))

>>> from math import sqrt
>>> x=Point(0.0,0.0)
>>> y=Point(3.0,0.0)
>>> z=Point(3.0,4.0)
>>> T=Triangle(x,y,z)
>>> print T.Area()
6.0


 

כדאי לדעת:

גם הרשימה (list) מוגדרת באמצעות מחלקה.

דגש לגבי המשתנה self

עריכה

המשתנה self עלול להיות מבלבל. זהו "מצביע" ל-instance, כלומר למופע הספציפי של מחלקה מסוימת. מספר דגשים:

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

הרחבה לגבי מוסכמות בכתיבת מחלקות

עריכה

מתודת הקונסטרקטור __init__

עריכה

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

>>> d1 = dict()
>>> d1['x'] = 3; d1['y'] = 4
>>> d1
{'y': 4, 'x': 3}


>>> d2 = dict([('x',3), ('y',4)])
>>> d2
{'y': 4, 'x': 3}

במקרה הראשון, המתודה __init__ של המחלקה dict לא קיבלה אף פרמטר, ולכן יצרה מופע של מילון ריק, ואילו במקרה השני הועברה ל-init רשימה עם זוגות (key,value) אשר מהן ה-init יצר מילון עם ערכים "ראשוניים", דיפולטיביים.

משתנה התיעוד __dict__

עריכה

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

>>> print list.__doc__
>>> help(list)


- מחלקות -