דילוג לתוכן
  • חוקי הפורום
  • פופולרי
  • לא נפתר
  • משתמשים
  • חיפוש גוגל בפורום
  • צור קשר
עיצובים
  • 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 כותבים 49 צפיות 1 עוקבים
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
תגובה
  • תגובה כנושא
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • 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
                      • חוקי הפורום
                      • פופולרי
                      • לא נפתר
                      • משתמשים
                      • חיפוש גוגל בפורום
                      • צור קשר