OOP: Property Decorators - Arabic


لو فرضا عندنا الكود التالي:

class Employee:
    def __init__(self, first, last):
        self.first = first
        self.last = last
        self.email = first + "." + last + '@email.com'

    def fullname(self):
        return f"{self.first} {self.last}"

 

اخدنا Instance وعملنا منها Object

 

user = Employee('Mohamed', 'Ayman')

 

استدعينا الـ Method والـ Attributes

 

# Get first name
print(user.first)
# Get last name
print(user.last)
# Get fullname
print(user.fullname())
# Get email address
print(user.email)

 

عملت تغيير للـ Instance Variable

 

user.first = 'Sara'
user.last = 'Hassen'

 

استدعينا نفس الـ Method والـ Attributes

 

# Get first name
print(user.first)
# Get last name
print(user.last)
# Get fullname
print(user.fullname())
# Get email address
print(user.email)

 

الـ Output

 

Sara
Hassen
Sara Hassen
Mohamed.Ayman@email.com

 

هتلاقي مشكلة بالـ Output, هي ان تم التغيير بالكل ولكن فضل الايميل زي ما هو, لان الايميل عبارة عن Variables معتمد بشكل مباشر على الـ Instance Variable الـ هي:

 

def __init__(self, first, last)

 

لكن مش زي الـ First والـ Last الـ معتمدين على الـ Class Variable الـ هما:

 

self.first = first
self.last = last

 

ممكن اعمل Email Method وتعتقد ان المشكلة اتحلت كالتالي:

 

def email(self):
        return f'{self.first}.{self.last}@email.com'

 

 

لكن هتكون في مشكلة اكبر اننا هنطر نغير كل الكود بتاعنا يداوينا من Email Attribute

 

print(user.email)

 

الي Email Method

 

print(user.email())

 

ولو حد مستخدم الكود الخاص بينا هيحصل عنده Error

 

 

Getter

الحل عشان تعدي مشكلة التعديل اليدوي او ظهور الـ Error عند الناس المستخدمة الكود, اننا نحول الـ Method لـ Attribute باستخدام الـ Getter

 

يعني فعلا احنا هنعمل Email Method لكن هنستدعيها كـ Attribute, يعني ولا هنغير كود ولا هيحصل Error

 

الكود كـ التالي:

** هكتب نفس الـ Employee Class

** لكن بدل الـ Email Attribute

** احولها لـ Email Instance

** واضيف كلمة property

** عشان استدعي الـ Instance كـ Attribute

 

class Employee:
    def __init__(self, first, last):
        self.first = first
        self.last = last
        # remove email attribute
        # self.email = first + "." + last + '@email.com'

    # Create email instance and add Getter
    @property
    def email(self):
        return f'{self.first}.{self.last}@email.com'

    def fullname(self):
        return f"{self.first} {self.last}"

 

Setter

دلوقتي:

** هاخلي الـ fullname كـ Attribute

 

@property
def fullname(self):
    return f"{self.first} {self.last}"

 

** هاتعامل الـ fullname كـ Attribute

** و Assign new value للـ fullname, كالتالي:

 

user.fullname = 'Mohamed Ayman'

 

عند الـ Executions هيظهر الـ Error التالي:

 

AttributeError: can't set attribute

 

صحيح ان دلوقتي الـ fullname بيتم التعامل معاه كـ Attribute لكن البنية بتاعته مش Attribute

 

الـ Setter بتمكني اني اضيف خاصية الـ Attribute والـ هي عمل Assignment كالتالي:

 

@fullname.setter
def fullname(self, value):
    first, last = value.split(' ')
    self.first = first
    self.last = last

 

حيث أن الـ Value هي القيمة الـ بعد الـ علامة '=', هنا:

 

user.fullname = 'Mohamed Ayman'

 

دلوقتي لو عملت Execution

 

print(user.fullname)

 

الـ Output

 

Mohamed Ayman
Mohamed.Ayman@email.com

 

 

Deleter

واخيرا الـ Deleter الـ بتتعامل مع الـ del keyword

 

لو جربت اعمل del للـ fullname attribute

 

del user.fullname

 

الـ Error التالي:

 

AttributeError: can't delete attribute

 

فـ بنستخدم الـ Delleter كالتالي:

 

@fullname.deleter
def fullname(self):
    print('Delete name!')
    self.first = None
    self.last = None

 

 

الكتابة الـ داخل الكود اختيارية, يعني ممكن تكتب Pass عادي, كالتالي:

 

@fullname.deleter
def fullname(self):
    pass

 

الكود المستخدم من الـ Video tutorial دي