آموزش کپسوله سازی در پایتون
کپسولهسازی(Encapsulation) در پایتون، به محافظت از دادهها در درون یک کلاس گفته میشود. کپسولهسازی یعنی اینکه از دادهها(پروپرتیها) و متدها با هم در یک کلاس، نگهداری کنیم؛ به طوری که که نحوه دسترسی به دادهها از خارج از این کلاس را کنترل کنیم. این کار از تغییرات تصادفی در دادههای شما جلوگیری میکند و جزئیاتِ داخلیِ نحوهی عملکرد کلاس شما را پنهان میکند.
پروپرتیهای خصوصی(Private) در پایتون
در پایتون، میتوانیم با استفاده از پیشوندِ __ (دو آندرلاین) باعث شویم که پروپرتیها، خصوصی(private) شوند.
مثال شماره 1
ایجاد یک پروپرتیِ کلاسِ خصوصی(private) به نام __age:
class Person:
def __init__(self, name, age):
self.name = name
self.__age = age # این پروپرتی خصوصی است
p1 = Person("Emil", 25)
print(p1.name)
print(p1.__age) # این باعث ایجاد یک خطا می شود
نتیجه:
Emil
Traceback (most recent call last):
File "./prog.py", line 8, in <module>
AttributeError: 'Person' object has no attribute '__age'
امتحان کنیدنکته: ما نمیتوانیم به پروپرتیهای خصوصی، مستقیماً در بیرون از کلاس دسترسی پیدا کنیم.
دریافت مقدار از پروپرتیهای خصوصی
برای دسترسی به یک پروپرتی خصوصی(private)، میتوانید یک متد دریافتکننده(getter) ایجاد کنید:
مثال شماره 2
استفاده از یک متد دریافت کننده(getter) برای دسترسی به یک پروپرتی خصوصی:
class Person:
def __init__(self, name, age):
self.name = name
self.__age = age
def get_age(self):
return self.__age
p1 = Person("Tobias", 25)
print(p1.get_age())
نتیجه:
25
امتحان کنیدتنظیم کردنِ(set) مقدار برای پروپرتیهای خصوصی
برای تغییر دادن مقدار یک پروپرتی خصوصی(private)، میتوانیم یک متد تنظیمکننده(setter) ایجاد کنیم. متد تنظیمکننده(setter) همچنین میتواند مقدار مورد نظر را قبل از اینکه تنظیم شود، اعتبارسنجی کند:
مثال شماره 3
استفاده از یک متد تنظیم کننده(setter) برای تغییر داد مقدار یک پروپرتی خصوصی:
class Person:
def __init__(self, name, age):
self.name = name
self.__age = age
def get_age(self):
return self.__age
def set_age(self, age):
if age > 0:
self.__age = age
else:
print("Age must be positive")
p1 = Person("Tobias", 25)
print(p1.get_age())
p1.set_age(26)
print(p1.get_age())
نتیجه:
25
26
امتحان کنیدچرا از کپسولهسازی استفاده کنیم؟
کپسولهسازی از مزیتهای زیر برخوردار است:
- محافظت از دادهها: از تغییرات تصادفی دادهها جلوگیری میکند.
- اعتبارسنجی: ما میتوانیم دادهها را قبل از اینکه تنظیم(set) شوند، اعتبارسنجی کنیم.
- انعطافپذیری: پیادهسازیداخلی(Internal implementation) میتواند بدون تاثیر بر کدهای اکسترنال، تغییر کند.
- کنترلپذیری: ما کنترل کاملی روی چگونگی دسترسی به مقدار دادهها و تغییر آنها داریم.
مثال شماره 4
استفاده از کپسولهسازی برای محافظت و اعتبارسنجی داده ها:
class Student:
def __init__(self, name):
self.name = name
self.__grade = 0
def set_grade(self, grade):
if 0 <= grade <= 100:
self.__grade = grade
else:
print("Grade must be between 0 and 100")
def get_grade(self):
return self.__grade
def get_status(self):
if self.__grade >= 60:
return "Passed"
else:
return "Failed"
student = Student("Emil")
student.set_grade(85)
print(student.get_grade())
print(student.get_status())
نتیجه:
85
Passed
امتحان کنیدپروپرتیهای محافظت شده(protected)
پایتون همچنین قراردادی برای استفاده از پروپرتیهای محافظتشده(protected) با استفاده از یک پیشوند _ ( یک آندرلاین) دارد:
مثال شماره 5
ایجاد یک پروپرتی محافظت شده(protected):
class Person:
def __init__(self, name, salary):
self.name = name
self._salary = salary # پروپرتی محافظت شده
p1 = Person("Linus", 50000)
print(p1.name)
print(p1._salary) # می تواند دسترسی داشته باشد، اما نباید دسترسی داشته باشد
نتیجه:
Linus
50000
امتحان کنیدنکته: یک آندرلاین تکی _ تنها یک قرارداد است. این آندرلاین به دیگر برنامهنویسان میگوید که این پروپرتی برای استفادهی داخلی در نظر گرفته شده است، اما پایتون این محدودیت را اعمال نمیکند.
استفاده از متدهای خصوصی(Private)
ما همچنین میتوانیم با استفاده از دو علامت آندرلاین به عنوان پیشوند، باعث شویم که متدها خصوصی(private) شوند:
مثال شماره 6
ایجاد یک متد خصوصی(private):
class Calculator:
def __init__(self):
self.result = 0
def __validate(self, num):
if not isinstance(num, (int, float)):
return False
return True
def add(self, num):
if self.__validate(num):
self.result += num
else:
print("Invalid number")
calc = Calculator()
calc.add(10)
calc.add(5)
print(calc.result)
# calc.__validate(5) # این یک خطا ایجاد می کند
نتیجه:
15
امتحان کنیدنکته: مانند پروپرتیهای خصوصی(private) که از دو آندرلاین استفاده میکردند، متدهای خصوصی(private) نیز نمیتوانند مستقیماً در بیرون از کلاس فراخوانی شوند. بنابراین متد __validate تنها میتواند توسط دیگر متدهای درون کلاس، مورد استفاده قرار گیرد.
دستکاری کردن نام ها
به روشی که پایتون پروپرتیها و متدهای خصوصی را پیادهسازی میکند، دستکاری کردن نامها(Name mangling) گفته میشود. وقتی که ما از دو علامت آندرلاین __ استفاده میکنیم، پایتون به طور خودکار به صورت داخلی آن را با اضافه کردن _ClassName در جلوی آن، تغییرنام میدهد. بعنوان مثال، __age به _Person__age تبدیل میشود.
مثال شماره 7
دیدن اینکه چگونه پایتون نام های مورد نظر را دستکاری می کند:
class Person:
def __init__(self, name, age):
self.name = name
self.__age = age
p1 = Person("Emil", 30)
# این روشی است که پایتون نام های مورد نظر را دستکاری می کند
print(p1._Person__age) # این کار توصیه نمی شود
نتیجه:
30
امتحان کنیدنکته: با اینکه میتوانیم با استفاده از نام دستکاری شده(mangled name) به پروپرتیهای خصوصی(private) دسترسی پیدا کنیم، اما استفاده از این کار توصیه نمیشود. زیرا هدف کپسولهسازی را با شکست مواجه میکند.
منبع: www.w3schools.com/python
- بازدید: 60
1. سعی کنید نظرات شما مرتبط با مقاله ی مورد نظر باشد، در غیر این صورت پاسخ داده نخواهد شد.
2. سوالات خود را به صورت کوتاه بیان کنید و از پرسیدن چند سوال به طور همزمان خودداری کنید.
3. سوال خود را به طور واضح بیان کنید و از کلمات مبهم استفاده نکنید.