טיפול ב-attributes

טיפול ב-attributes 

__getattr__, __setattr__ , __delattr__

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

 

class MyAttributes:

    def __init__(self):
        self.data = {'a': 'alfa', 'b': 'beta'}

    def __getattr__(self, attr):
        return self.data[attr]

obj = MyAttributes()
d=obj.a
print(d)     

 

>>>

alfa

 

 

בדוגמא למעלה, אנו מעבירים במסגרת המתודה המיוחדת __init__ שורה של תכונות (attributes) בתוך מילון. תכונה a היא alfa תכונה b היא beta. כדי להגיע לתכונה מסוימת דווקא ברשימת התכונות, אנו נזקקים ל- __getattr__ ולאחר ששיבצנו את המתודה במחלקה שלנו אנו יכולים לגשת לתכונה מסוימת ולראות אותה.

כאשר אנו רוצים להוסיף באותו אופן תכונה נוספת לרשימה שלנו שתגיב ל- obj.c שעדיין לא קיימת, הדברים מעט מסתבכים, קחו אוויר, וננסה להסביר מה עושה המתודה המיוחדת __setattr__ ולמה זה יותר מסובך. פייתון משתמשת באותה שיטה כדי לבצע השמה של attribute ולכן שימוש אינטואיטיבי בפונקציה מהצורה self.data[key]=value כאשר מתודת __init__ נותרת כפי שהיא - יגרום לרקורסיה אינסופית -  ()__setattr__ תקרא לעצמה....

לבעיה הזאת יש כמה פתרונות – שהבא מביניהם נראה לי יותר אלגנטי והוא גם קרוי בפייתון new style כך שאין מצב למשהו ב- old style.

 

 

class MyAttributes:

    def __init__(self):
        object.__setattr__(self,"data", {'a': 'alfa', 'b': 'beta'})
    def __getattr__(self, key):
        return self.data[key]
    def __setattr__(self, key, value):
            self.data[key]=value
    def __repr__(self):
        return f"{self.data}"

obj = MyAttributes()

obj.c="cool"
print(obj)

 

אנו קוראים למחלקה הבסיסית באמצעות ()object.__setattr__ כדי לחמוק מ- ()__setattr__

והרקורסיה הכרוכה בו.

 

התוצאה

{'a': 'alfa', 'b': 'beta', 'c': 'cool'}

 

 

הצלחנו לשבץ תכונה חדשה תחת השם c, זה cool.  בלי לגרום לרקורסיה אינסופית.

באותו אופן גם הטיפול ב- __delattr__ עובר באופן חלק – ואנו מצליחים למחוק תכונה מהמחלקה שלנו.

 

 

class MyAttributes:

    def __init__(self):
        object.__setattr__(self,"data", {'a': 'alfa', 'b': 'beta'})
    def __getattr__(self, key):
        return self.data[key]
    def __setattr__(self, key, value):
        self.data[key]=value
    def __delattr__(self, key):
        del self.data[key]
    def __repr__(self):
        return f"{self.data}"

obj = MyAttributes()

obj.c="cool"
del obj.a
print(obj)

 

הנה, מחקנו attribute

 

התוצאה

{'b': 'beta', 'c': 'cool'}

Please reload

Please reload

רעננו את הדף והקליקו למעבר לנושא הבא: