לדלג לתוכן

5.2 סטטי הרצאה

סטטי - static

  • "סטטי" - static בOOP זה תכונה שאפשר להביא לממברים של מחלקות שהופכות אותם ל- "גלובליות". מה זה אומר?

שדה סטטי

  • שדה סטטי הוא שדה שניתן לגשת אילו ישירות מהמחלקה, מבלי לצור אובייקט למחלקה.
  • הנה דוגמה להגדרת שדה סטטי "legs" למחלקה Dog שלנו עם ערך ברירת מחדל של 4:
    class Dog:  # The Dog class
        legs = 4 # Static class field
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def bark(self):
            print("bark bark")
    
        def get_legs(self):
            self.bark()
            return self.legs
    
        def my_name(self):
            self.bark()
            print(f"my name is {self.name}")
    
  • עכשיו נוכל לגשת ישירות למשתנה הזה גם מבלי ליצור אובייקט חדש:
    print(Dog.legs)  # Static reference
    Dog.legs = 5  # Static reference
    
  • כמובן שנוכל לגשת אילו גם עם יצירת אובייקט חדש:
    my_dog = Dog(name="max", age=3)  # First dog
    print(my_dog.legs)
    my_dog.legs = 5
    
    my_dog.get_legs()  # Will return 5
    

מתודה סטטית

  • כמו שאפשר להגדיר שדה סטטי אפשר להגדיר גם מתודה סטטית, מתודה סטטית היא מתודה שאפשר לגשת אלייה ישירות, מבלי לצור אובייקט של המחלקה
  • ניצור מתודה כזו באמצעות שימוש בדקורטור "staticmethod", המובנה בפייתון בדרך הבאה:
    class Dog:  # The Dog class
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        @staticmethod
        def bark():
            print("bark bark")
    
        def my_name(self):
            self.bark()
            print(f"my name is {self.name}")
    
  • גישה למתודה סטטית ישירות מבלי ליצור אובייקט:
    Dog.bark()  # Static reference
    
  • הנה קריאה למתודה עם יצירת אובייקט:
    my_dog = Dog(name="max", age=3)  # Dog
    my_dog.bark()  # Would work too
    
  • שימו לב: שאנחנו מגדירים מתודה סטטית אין לה "self", הסיבה לכך היא שאנחנו לא יכולים לגשת לשדות דינמים (לא סטטים) מבלי שיצרנו אובייקט, אז זה לא הגיוני שמתודה סטטית תוכל לגשת למשל למשתנים שנוצרים עם init.
  • בגלל שאין לנו self במתודה סטטית, גם אם היינו רוצים לכתוב פונקציה סטטית שרק ניגשת לשדה סטטי כמו legs, לא היינו יכולים. בגלל שאין לנו שום דרך, למורות שlegs נוצר גם אם אין אובייקט חדש, וזה בעייתי.

מתודת קלאס

  • לפעמים אנחנו רוצים לצור מתודות סטטיות שיכולות לגשת לערכים סטטים של המחלקה.
  • מתודת קלאס זהה לחלוטין למתודה סטטית, רק שמתודת קלאס יכולה בנוסף לגשת לממברים סטטים במחלקה ובכך היא פחות מוקבלת. אז היא מקבלת פרמטר שדומה לself שנקרא לו cls. (קיצור של class)
  • נגדיר מתודת class עם דקורטור - "classmethod", המובנה בפייתון בדרך הבאה:
    class Dog:  # The Dog class
        legs = 4 # Static class field
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        @staticmethod
        def bark():
            print("bark bark")
    
        @classmethod
        def get_legs(cls):
            cls.bark()
            return cls.legs
    
        def my_name(self):
            self.bark()
            print(f"my name is {self.name}")
    
  • כתבנו מתודת קלאס שיכולה לגשת לממברים סטטים, נוכל לגשת אלייה מבלי ליצור אובייקט חדש של המחלקה:
    Dog.get_legs()  # Static reference
    
  • נוכל לגשת אלייה גם אם יצרנו אובייקט חדש:
    my_dog = Dog(name="max", age=3)  # Dog
    my_dog.get_legs()  # Would work too
    

טייפ הינטינג לשדות סטטים

  • כמו לפרמטרים של פונקציות אפשר לעשות type hinting לשדות סטטים של מחלקות
    class Dog:  # The Dog class
        legs: int = 4 # Static class field
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def get_legs(self):
            self.bark()
            return self.legs
    

מדוע להשתמש בממברים סטטים?

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