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 دي