דילוג לתוכן
  • חוקי הפורום
  • פופולרי
  • לא נפתר
  • משתמשים
  • חיפוש גוגל בפורום
  • צור קשר
עיצובים
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • ברירת מחדל (ללא עיצוב (ברירת מחדל))
  • ללא עיצוב (ברירת מחדל)
כיווץ
מתמחים טופ
  1. דף הבית
  2. קטגוריות בהרצה
  3. תכנות
  4. Python
  5. מדריכים - Python
  6. מדריך | פייתון קלאסים (Classes) - תכנות מונחה עצמים (OOP) המדריך המלא

מדריך | פייתון קלאסים (Classes) - תכנות מונחה עצמים (OOP) המדריך המלא

מתוזמן נעוץ נעול הועבר מדריכים - Python
12 פוסטים 1 כותבים 57 צפיות 1 עוקבים
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
תגובה
  • תגובה כנושא
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • H מחובר
    H מחובר
    hartkhartk
    כתב נערך לאחרונה על ידי
    #1

    המדריך הזה נכתב ללא בינה מלכותית (כן נעזרתי בו לחידוד הנקודות במדריך אבל בסוף זה כתיבה שלי)

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

    פייתון קלאסים (Classes) - תכנות מונחה עצמים (OOP) המדריך המלא

    פרק 1 אז נתחיל. מה זה בכלל קלאסים?

    אפשר לראות את הקלאסים כתבנית שאתה מגדיר לו מבנה כרצונך ואז יוצר הרבה הרבה יחידות (מופעים) במבנה הזה בתכנים משתנים
    לדוגמה אתה יוצר קלאס מכונית שמוגדר עם תכונות אלו: חברה, צבע, קילומטרז
    ואז אתה יוצר מופע אחד עם טיוטה, לבן, 150
    ואז אתה יוצר עוד מופע עם יונדאי, שחור, 200
    ואז עוד מופע עם מרצדס, אפור, 300
    כך אנחנו לא צריכים להגדיר כל פעם מחדש את המבנה, אלא משתמשים בתבנית אחת ומייצרים ממנה אובייקטים שונים

    דוגמת קוד עם הסבר שורה שורה

    # יצירת קלאס
    class Car:
        # בניית האובייקט (constructor) (יוסבר לעומק בחלק 2)
        def __init__(self, company, color, km):
            self.company = company  # שם החברה של הרכב
            self.color = color      # צבע הרכב
            self.km = km            # קילומטראז'
    
    # יצירת מופעים (אובייקטים)
    car1 = Car("Toyota", "White", 150)
    car2 = Car("Hyundai", "Black", 200)
    car3 = Car("Mercedes", "Gray", 300)
    
    print(type(car1))  # <class '__main__.Car'>
    
    
    print(car1.company)  # Toyota
    

    הסברים
    כל מופע זה משתנה שמכיל אוביקט קלאס אם תעשו ```

    print(type(car1))
    

    זה יחזיר

    <class '__main__.Car'>
    

    בחלק

    print(car1.company)
    

    אתה ניגש לערך הספציפי למופע שלו קראת שבמיקום הקבוע בתבנית
    כלומר שב-car1 הגדירו

    car1 = Car("Toyota", "White", 150)
    

    אז המיקום שבקלאס

    self.company = company
    

    יהיה Toyota
    מה שאומר ש

    print(car1.company)
    

    ידפיס Toyota

    תגובה 1 תגובה אחרונה
    2
    • H מחובר
      H מחובר
      hartkhartk
      כתב נערך לאחרונה על ידי
      #2

      פרק 2 self

      אז נתחיל עם self (תרגום לעברית של self זה עצמי (הכוונה לאובייקט המופע עצמו))
      הוא בעצם אובייקט המופע שנוצר מהקלאס
      כך שאם נעשה

      car1 = Car("Toyota", "White", 150)
      

      car1 זה אובייקט שמכיל company, color , km
      אז עם אתה רוצה לגשת אל

      car1.company
      

      אתה בעצם ניגש אל

      self.company
      

      כי self זה האובייקט שנוצר מהקלאס
      עכשיו נניח שאתה עושה כך:

      car1 = Car("Toyota", "White", 150)
      car2 = Car("Hyundai", "Black", 200)
      car3 = Car("Mercedes", "Gray", 300)
      

      אז כל אובייקט זה self נפרד!
      כך שה self שנקרא בשם car1 ב-

      self.company
      

      יחזיר

      "Toyota"
      

      אבל ה self שנקרא בשם car2 באותו מיקום

      self.company
      

      יחזיר

      "Hyundai"
      

      וה- self שנקרא car3
      באותו מקום בדיוק

      self.company
      

      יחזיר

      "Mercedes"
      

      אבל בשביל מה צריך את self?

      למה לא להשתמש בשם האובייקט?

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

      class Fun_class:
          word_1 = "fun"
          word_2 = "class"
          def print_1(self):
              print(self.word_1)
          
          def print_2(self):
              print(self.word_2)
      

      אתה מעביר לפונקציה self
      שזה אומר שכל מה שנמצא בקלאס כולל המשתנה והפונקציה עצמה עוברים לפונקציה
      כך שבתוך הפונקציה אתה יכול לקרוא לאוביاקט self על כל תוכנו
      מה שמאפשר לך לקרוא למשתנים הראשיים ולפונקציה השנייה מתוך הראשונה
      בגלל שהמשתנים ושני הפונקציות הם חלק מה-self והפונקציות קיבלו את אותו ה-self
      ועוד יותר מזה אתה יכול לשנות את המשתנה הראשי מתוך הפונקציה!
      כי זה מתפקד כמשתנה גלובלי לכל המופע

      דוגמה

      class Fun_class:
          word = "fun"
          def print(self):
              print(self.word)
          
          def change_word(self):
              self.word = "fun_class"
      
      Fun_obg = Fun_class()
      Fun_obg.print()
      Fun_obg.change_word()
      Fun_obg.print()
      

      בדוגמה זו רואים שהפונקציה change_word משנה את המשתנה word הגלובלי לכל ה-self אבל לא ל-self (כלומר מופע) אחר

      אבל איך self עובד מאחורי הקלעים?

      נניח שעכשיו עושים כך

      Fun_obg = Fun_class()
      Fun_obg.print()
      

      אז פייתון יעשה מאחורי הקלעים כך

      Fun_class.print(Fun_obg)
      

      שהוא בעצם מריץ את הקלאס הקבוע על self-מופע ספציפי

      תגובה 1 תגובה אחרונה
      0
      • H מחובר
        H מחובר
        hartkhartk
        כתב נערך לאחרונה על ידי
        #3

        פרק 3 Constructor - בנאי

        אז הבנאי (Constructor) זו פונקציה שמוגדרת בקלאס ורצה על כל מופע בזמן יצירתו
        מה שמאפשר להגדיר משתנים, לקבל פרמטרים, ולעשות לוגיקה על כל מופע אוטומטי ביצירה
        ההגדרה נעשה כך

        class Fun_class:
            def __init__(self):
                self.word = "fun"
        

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

        קבלת פרמטרים

        ביצירת בנאי אתה יכול להעביר לבנאי פרמטרים כך

        class Fun_class:
                def __init__(self, word):
                    self.word = word
        

        מה שקורה בקוד זה בשורה הראשונה מגדירים קלאס

        class Fun_class:
        

        בשורה השנייה מגדירים בנאי (בגלל שזה הבנאי אז כל פרמטר בפונקציה זה פרמטר לקלאס)

        def __init__(self, word):
        

        ובשורה השלישית מוסיפים את תוכן הפרמטרים ל-self (ובגלל שזה הבנאי זה יוגדר אוטומטית לכל מופע ביצירתו)

        self.word = word
        

        ואז ביצירת קלאס מעבירים את הפרמטר כך

        Fun_obg = Fun_class("fun") # "fun" זה הפרמטר
        
        תגובה 1 תגובה אחרונה
        0
        • H מחובר
          H מחובר
          hartkhartk
          כתב נערך לאחרונה על ידי
          #4

          פרק 4 משתני self מול משתני class

          על משתני self כבר נכתב בפרק 2 שזה משתנים שמוגדרים בקלאס ותוכנם משתנה ממופע למופע
          אז מה זה משתני קלאס?
          משתני קלאס זה משתנים שגם מוגדרים בקלאס אבל תוכנם קבועים לכל המופעים
          כלומר שאם תשנה את זה במופע אחד זה ישתנה בכל המופעים
          בשביל לכתוב כזה משתנה פשוט תורידו את ה-self
          לדוגמה

          class Fun_class:
              word = "fun"
          

          ועכשיו אם תעשה

          Fun_obg_1 = Fun_class()
          Fun_obg_2 = Fun_class()
          Fun_class.word = "class"
          print(Fun_obg_1.word) # יחזיר class
          print(Fun_obg_2.word) # גם יחזיר class
          

          שני המופעים ישתנו כי שינית את הקלאס עצמו
          אבל אם תעשה את השינוי דרך המופע כך

          Fun_obg_2.word = classes
          

          זה לא ישנה את הקלאס אלא ייצור משתנה חדש בתוך ה-self של המופע הזה

          תגובה 1 תגובה אחרונה
          0
          • H מחובר
            H מחובר
            hartkhartk
            כתב נערך לאחרונה על ידי
            #5

            פרק 5 מתודות: מתוודות רגילות, מתודות סטטיות, ומתודות קלאס

            אז כל פונקציה בקלאס נקראת מתודה
            ומגדירים אותו כך

            class Fun_class:
                def print_fun(self):
                    print("This is a function in a class")
            

            ובשביל להפעיל צריך ליצור מופע כך

            obj = Fun_class()
            

            ואז אפשר להפעיל את המתודה כך

            obj.print_fun()
            

            אז למה צריך להעביר למתודה רגילה self?

            כי self זה אובייקט המופע ולכן כל פעם שמפעילים את הקלאס.פונקציה אז בעצם מפעילים את הקלאס.פונקציה על המופע-self שממנו קוראים לזה (ואני ישים בספוילר את ההסבר של איך עובד self ממה שכבר נכתב בסוף פרק 2)

            אבל איך self עובד מאחורי הקלעים?
            נניח שעכשיו עושים כך

            Fun_obg = Fun_class()
            Fun_obg.print()
            

            אז פייתון יעשה מאחורי הקלעים כך

            Fun_class.print(Fun_obg)
            

            שהוא בעצם מריץ את הקלאס הקבוע על self-מופע ספציפי

            מתודות סטטיות

            מטודות סטטיות אלו פונקציות קלאס סטטיות
            כשמגדירים אותם אין פרמטר חובה (בשונה מהמתודות הרגילות שחיבות פרמטר self)
            שזה אומר שהם לא קשורים אל ה-self-מופע
            המתודות-פונקציות האלו נקראים ללא מופע
            אלא ישירות מהשם של הקלאס
            אבל בגלל שזה לא קשור ל-self גם אין לזה קשר לשאר הקלאס
            כלומר שזה מתנהג כמו פונקציה רגילה שנמצאת בקלאס רק לאירגון
            הם נכתבים פשוט עם @staticmethod בשורה לפני פתיחת הפונקציה
            דוגמה

            class Fun_class:
            	@staticmethod
            	def print_word():
            		print("word")
            

            ועכשיו תוכל לקרוא לזה מהשם של הקלאס ישירות ללא מופע
            דוגמה לקריאה

            Fun_class.print_word
            

            אבל בשביל מה זה שימושי מתודות סטטיות?

            אז השימושיות הכי נפוצה למתודה סטטית זה כשהפונקציה-מתודה עושה לוגיקה שקשורה לקלאס בלי לגשת לנתוני המופע

            מתודות קלאס

            מתודות קלאס אלו מתודות שבמקום אובייקט מסוג self הם מקבלים אובייקט מסוג cls

            אז מה זה אובייקט cls?

            cls זה כפשוטו אובייקט הקלאס עצמו (במקום אובייקט המופע שזה self)
            שזה אומר שהם גם לא קשורים אל ה-self-מופע
            אבל הם גם לא מנותקים משאר הקלאס
            מה שאומר שיש להם גישה למשתני אובייקט (ראה פרק 4)
            אבל אין להם גישה למשתני self-מופע
            כשמגדירים אותם חייבים להוסיף פרמטר cls (במקום self במתודות רגילות)
            הם נקראים ישירות מהשם של הקלאס (כמו מתודה סטטית)
            אבל יש להם גישה לאובייקט cls-קלאס של הראשי (ולא של המופע)
            בשונה ממתודה סטטית שאין לזה בכלל גישה לשאר הקלאס
            הם נכתבים פשוט עם @classmethod בשורה לפני פתיחת הפונקציה ופרמטר cls
            דוגמה

            class Fun_class:
            	word = "hello" # בלי self!
            	@classmethod
            	def print_word(cls): # פרמטר cls
            		print(cls.word) # כמו self.word  רק מהקלאס ישירות ולא ממופע
            

            ועכשיו תוכל לקרוא לזה מהשם של הקלאס ישירות ללא מופע
            דוגמה לקריאה

            Fun_class.print_word
            

            סיכום ההבדלים בין מתודות רגילות, מתודות סטטיות, ומתודות קלאס

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

            אבל מתי להשתמש בכל סוג?

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

            תגובה 1 תגובה אחרונה
            0
            • H מחובר
              H מחובר
              hartkhartk
              כתב נערך לאחרונה על ידי
              #6

              פרק 6 Encapsulation - הסתרת מידע

              אז איך מסתרים על תוכן מהקלאס?
              אז יש שני דרכים

              1 _var (קו תחתון לפני הגדרת המשתנה)

              זה נכתב כך

              class printer:
              	_word = "hello"
              

              שימו לב שזה לא משנה כלום בהתנהגות הקוד!
              אלא רק משמש כסימן מוסכם שזה משתנה פנימי שלא אמורים לשנות מבחוץ

              2 __var (שני קווים תחתונים לפני הגדרת המשתנה)

              זה כבר הפחתת טעויות אמיתית אבל בתור הסתרה זה נעקף בקלות
              זה נכתב כך

              class printer:
              	__word = "hello"
              

              וזה בעצם משנה את השם שנשמר באחורי הקלעים משם המשתנה

              	__word
              

              אל שם קו תחתון שם הקלאס ואז השם שכולל שני קווים תחתונים לפני
              כלומר שזה

              class printer:
              	__word = "hello"
              

              נשמר למעשה (באחורי הקלעים) כך

              _printer__word
              

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

              תגובה 1 תגובה אחרונה
              0
              • H מחובר
                H מחובר
                hartkhartk
                כתב נערך לאחרונה על ידי
                #7

                פרק 7 property מנגנון שליטה בגישה למשתנה

                אז מה זה property?
                property בעצם מאפשר לך לגשת לפונקציה כאילו שזה משתנה
                בעצם אתה עושה @property שורה לפני ואז אתה עושה פונקציה ששם הפונקציה זה שם המשתנה ותוכן המשתנה זה מה שהפונקציה הזו תחזיר ב-return
                כך שכשנגדיר כך

                class printer:
                	def __init__(self, word):
                		self._word= word
                	@property
                	def word(self):
                	        return "word"
                

                הטייפ של ההבטחה word זה תוכן ה-return כי זה לא פונקציה אלא משתנה שמתחבא בפונקציה
                ולכן כל פעם שנעשה אחרי זה כך

                obj = printer(10)
                print(obj.word)
                

                זה יקרא את word כפונקציה ויחזיר את ה-return כמשתנה
                אז בשביל מה צריך את זה?
                התשובה זה שאתה יכול להכניס לוגיקה שלפיו זה יחזיר משהו
                זה אומר שאני יכול להגדיר כך

                class printer:
                	def __init__(self, num):
                                self.num = num
                	@property
                	def word(self):
                		if self.num > 5:
                			return "word"
                		else:
                			return "none"
                

                עכשיו זה בעצם יבדוק בכל מופע שבו מפעילים את זה ואם num גדול מ-5 יכיל המשתנה word אחרת יכיל המשתנה none

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

                ההגדרת property מגדיר את המשתנה ומשמש כ-getter
                אם תחסר עריכה לא תוכל לערוך (שזה טוב לפעמים)
                אם תחסר מחיקה לא תוכל למחוק (שזה גם טוב לפעמים)
                אז איך עושים עריכה ומחיקה?
                אז עריכה עושים כך

                	@word.setter
                	def word(self, val):
                		self._word = val
                

                ואז אתה יכול להוסיף לוגיקה לפני כל שינוי
                דוגמה

                	@word.setter
                	def word(self, val):
                		if val == "abc":
                			self._word = val
                

                ואותו רעיון למחיקה

                	@word.deleter
                	def word(self):
                		del self._word
                
                

                וגם כאן ניתן להכניס לוגיקה
                דוגמה

                	@word.deleter
                	def word(self):
                		if self._word:
                			del self._word
                
                תגובה 1 תגובה אחרונה
                0
                • H מחובר
                  H מחובר
                  hartkhartk
                  כתב נערך לאחרונה על ידי
                  #8

                  פרק 8 ירושה וקומפוזיציה

                  אז ירושה וקומפוזיציה הם שני שיטות להעביר קלאס אחד אל תוך השני
                  אז מה זה ירושה?

                  בירושה אתה בעצם מגדיר קשר בין מחלקות בזמן ההגדרה
                  כך שהשני בעצם מקבל גישה לכל מה שיש לראשון ומרחיב אותו
                  ירושה זה בעצם שהבן הוא סוג של האבא
                  מגדירים את הירושה כך

                  class Father:
                  	def father_print(self):
                  		print("father")
                  
                  class Son(Father): # מוסיפים בסוגריים את שם קלאס האב
                  	def son_print(self):
                  		print("son")
                  

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

                  son_obj = Son()
                  son_obj.father_print()
                  
                  אז מה זה קומפוזיציה?

                  אז בקומפוזיציה אתה בעצם יוצר קלאס אחד שיש לו משתנה של אובייקט מופע הקלאס השני##
                  כך שהוא יכול לגשת אל זה ב-self ולהשתמש בו כמו במופע של אובייקט אחר שנמצא בתוך המחלקה
                  דוגמה

                  class Engine:
                      def start(self):
                          print("start")
                  
                  class Car:
                      def __init__(self):
                          self.engine = Engine()
                  
                      def start(self):
                          self.engine.start()  # שימוש במופע של מחלקה אחרת
                  

                  כך בעצם משתמשים בקלאס מנוע בתוך ה-self של הקלאס רכב

                  אז מתי להשתמש בכל סוג?

                  אז תיקחו כלל אצבע
                  מתי שהקלאס המקבל הוא סוג של הקלאס הנותן (כמו שכלב הוא סוג של חיה ורולקס זה סוג של שעון) משתמשים בירושה
                  אבל מתי שהמקבל הוא לא "סוג של" באמת תעדיפו קומפוזיציה

                  ואוד כלל אצבע חשוב. תמיד תעדיפו קומפוזיציה!

                  אז למה הכלל הזה?
                  התשובה זה שירושה יוצרת קשר מאוד חזק שעלול לשבור את הקוד וליצור "עץ משפחתי" מאוד מורכב
                  קומפוזיציה לאומת זאת מאפשרת חיבור יותר גמיש

                  תגובה 1 תגובה אחרונה
                  0
                  • H מחובר
                    H מחובר
                    hartkhartk
                    כתב נערך לאחרונה על ידי
                    #9

                    פרק 9 Method Overriding - עקיפת שיטה ו-super() ו MRO - סדר החיפוש בירושה

                    אז מה זה Method Overriding?
                    Method Overriding זה כשקלאס אחד יורש שני ואז משתמש בגרסה משלו בפונקציה מהשני תוך דריסת הגרסה המקורית
                    ואני יכתוב דוגמה לירושה רגילה קודם שיראו את ההבדל

                    class Animal:
                        def speak(self):
                            print("צליל כללי")
                    
                    
                    class Dog(Animal):
                        pass
                    
                    
                    dog = Dog()
                    dog.speak()
                    

                    ואז הפלט יהיה

                    צליל כללי
                    
                    זה דוגמה לירושה רגילה שבו הבן משתמש בפונקציה מהאבא

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

                    class Animal:
                        def speak(self):
                            print("צליל כללי")
                    
                    
                    class Dog(Animal):
                        def speak(self):
                            print("הב הב!")
                    
                    
                    dog = Dog()
                    dog.speak()
                    

                    ואז הפלט יהיה

                    הב הב!
                    

                    מה שקורה כאן זה שמגדירים בבן פונקציה (מטודה) באותו שם של מתודת האב
                    מה שגורם לדריסת הגרסה מהאב ויצירת גרסת בן חדשה

                    אבל למה זה שימושי בכלל?

                    וכן זה שימושי בשביל ליצור מבנה כללי בקלאס האב שתוכנו ישתנה מבן לבן

                    שימוש ב-super()

                    אז מה זה super()?
                    אז super() זה כשאתה לא רוצה לדרוס לגמרי את פונקצית האב אלא לקחת אותו ולהסיף לו כרצונך
                    דוגמה

                    class Animal:
                        def speak(self):
                            print("צליל כללי")
                    
                    
                    class Dog(Animal):
                        def speak(self):
                            super().speak()
                            print("הב הב!")
                    

                    הפלט יהיה

                    צליל כללי
                    הב הב!
                    

                    בעצם מה ש-super() עושה זה לטעון את גרסת האב לתוך גרסת הבן שדורסת את גרסת האב

                    סדר החיפוש (MRO)

                    אז מה זה בכלל MRO?
                    אז MRO זה הסדר שבו פייתון מחפש מתודות ומאפיינים בקלאסים
                    לדוגמה בקוד הזה

                    class A:
                        def hello(self):
                            print("A")
                    
                    
                    class B(A):
                        def hello(self):
                            print("B")
                            super().hello()
                            
                    class C(B):
                        def hello(self):
                            print("C")
                            super().hello()
                    

                    אז כשאתה קורא ל-

                    super().hello()
                    
                    מהיכן הוא יודע לאיזה אוביקט לפנות, לבן או לאבא או לסבא?

                    וזה בדיוק MRO
                    שזה סדר חיפוש קבוע שכשאתה קורא למתודה זה בודק. יש אותו באובייקט עצמו? לא? הולך לאבא. יש אותו לאבא? לא? הולך לסבא. יש אותו בסבא? לא? מחזיר שגיאה.

                    ואם אתה רוצה לדעת מה סדר החיפוש בירושה ספציפית?

                    אז פשוט תבדוק כך

                    print(C.__mro__)
                    

                    ועל הדוגמה לעיל יהיה הפלט

                    (<class '__main__.C'>,
                     <class '__main__.B'>,
                     <class '__main__.A'>,
                     <class 'object'>)
                    

                    כלומר שסדר החיפוש זה

                    C → B → A → object
                    
                    תגובה 1 תגובה אחרונה
                    0
                    • H מחובר
                      H מחובר
                      hartkhartk
                      כתב נערך לאחרונה על ידי
                      #10

                      פרק 10 Polymorphism - ריבוי צורות

                      אז מה זה Polymorphism?
                      Polymorphism זה כשעושים כמה קלאסים אם אותו שם פונקציה-מטודה כשבכל קלאס זה עושה משהו אחר
                      למשל בדוגמה זו

                      class Dog:
                          def speak(self):
                              print("הב הב")
                      
                      
                      class Cat:
                          def speak(self):
                              print("מיאו")
                      

                      איך אתה יכול לעבור על אותו הפונקצית speak בכל הקלאסים בצורה אחידה?
                      אז עם Polymorphism אתה פשוט עושה ליסט של מופעים (לא צריך ליצור מופעים ואז להכניס לליסט אלא אפשר לעשות רשימה שמכילה יצירת מופעים)

                      animals = [Dog(), Cat()] # יצירת רשימת מופעים
                      
                      for animal in animals:
                          animal.speak()
                      

                      בעצם אתה עובר על כל המופעי קלאס ברשימה וניגש לאותו השם בכולם

                      שימוש ב-Polymorphism בירושה

                      נניח שיש קלאס אב כזה

                      class fader:
                          def name(self):
                              pass
                      

                      ואז שלושה יורשים כך

                      class son_1(fader):
                          def name(self):
                              return "son_1"
                      
                      class son_2(fader):
                          def name(self):
                              return "son_2"
                      
                      class son_3(fader):
                          def name(self):
                              return "son_3"
                      

                      בקוד זה כל בן דורס את הפונקציה name שבאב לגרסה שלו
                      קוד זה בעצם משתמש באב למבנה קבוע שתוכנו משתנה אצל כל בן
                      אבל אני רוצה לעבור על הגרסאות של כל הבנים. איך אני עושה את זה?
                      אז בלי Polymorphism זה יראה כך

                      son_1_instance = son_1().name()
                      son_2_instance = son_2().name()
                      son_3_instance = son_3().name()
                      

                      ואם Polymorphism זה יראה כך

                      list_of_sons = [son_1(), son_2(), son_3()]
                      
                      for son in list_of_sons:
                          son.name()
                      
                      תגובה 1 תגובה אחרונה
                      0
                      • H מחובר
                        H מחובר
                        hartkhartk
                        כתב נערך לאחרונה על ידי
                        #11

                        פרק 11 Dunder Methods (Magic Methods)

                        אז מה זה Dunder Methods (Magic Methods)?
                        Dunder Methods (Magic Methods) אלה מטודות מובנות שמאפשרות להגדיר את הקלאס
                        כותביים אותם כשם פונקציה עם שני מקף תחתון () לפני השם הקבוע ושני מקף תחתון () אחרי השם הקבוע
                        נניח שיש לנו קלאס כזה

                        class cla:
                        pass
                        

                        ומופע כזה

                        class_obj = cla()
                        

                        ואני יכתוב כאן את הנפוצות

                        1. init – בנאי (Constructor)

                        אותו אנחנו כבר מכירים
                        הוא מגדיר מה ירוץ על כל המופעים מיד עם יצירתם
                        אם לא תגדירו לא ירוץ אטומטית כלום

                        2. str – איך האובייקט מוצג

                        זה מגדיר מה יודפס במקרה שתעשה print על האוביקט קלאס

                        print(class_obj)
                        

                        כך שמה שיחזור ל return זה מה שיודפס
                        אם לא תגדירו אותו הפלט לprint יהיה משהו כמו

                        <__main__.A object at 0x000001F3A9C>
                        

                        3. repr – ייצוג למפתחים

                        זה כמו str אבל יותר טכני למפתחים

                        4. len – פונקציית len()

                        זה מגדיר מה יקרה אם נעשה len על האוביקט קלאס

                        len(class_obg)
                        

                        אם לא נגדיר זה יחזיר שגיאה

                        5. add – חיבור (+)

                        זה מגדיר מה יקרה אם נחבר אוביקטים כך

                        a = Number(5)
                        b = Number(3)
                        
                        c = a + b
                        print(c.value)
                        

                        6. eq – השוואה (==)

                        זה מגדיר מה יקרה אם נשווה בין אוביקטים כך

                        p1 = Person("A")
                        p2 = Person("A")
                        
                        print(p1 == p2)
                        

                        7. getitem – גישה עם []

                        מגדיר מה יקרה אם ניגש לאוביקט כך

                        class_obj[1]
                        

                        8. setitem – שינוי עם []

                        מגדיר מה יקרה אם ננסה לשנות את האוביקט כך

                        class_obj[1] = 3
                        

                        9. call – להפוך אובייקט לפונקציה

                        דוגמה

                        class Greeter:
                            def __call__(self, name):
                                print(f"שלום {name}")
                        
                        g = Greeter()
                        g("ישראל")
                        
                        תגובה 1 תגובה אחרונה
                        2
                        • H מחובר
                          H מחובר
                          hartkhartk
                          כתב נערך לאחרונה על ידי יוסי מחשבים
                          #12

                          נא לא להגיב כאן כל משוב יכול להכתב בנושא תגובות בקישור
                          https://mitmachim.top/topic/96753/מדריך-פייתון-קלאסים-classes-תכנות-מונחה-עצמים-oop-תגובות

                          תגובה 1 תגובה אחרונה
                          0
                          • יוסי מחשביםי יוסי מחשבים נעל נושא זה

                          • התחברות

                          • אין לך חשבון עדיין? הרשמה

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