به آموزشگاه مجازی سینا خوش آمدید!

آموزش کپسوله سازی در پایتون

امتیاز
(0)

کپسوله‌سازی(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

 

  • بازدید: 59

نوشتن دیدگاه

لطفا نظرات خود را بیان کنید. به سوالات در سریع ترین زمان پاسخ داده خواهد شد.اما به نکات زیر توجه کنید:
1. سعی کنید نظرات شما مرتبط با مقاله ی مورد نظر باشد، در غیر این صورت پاسخ داده نخواهد شد.
2. سوالات خود را به صورت کوتاه بیان کنید و از پرسیدن چند سوال به طور همزمان خودداری کنید.
3. سوال خود را به طور واضح بیان کنید و از کلمات مبهم استفاده نکنید.

ارسال