۱۱/۲۲/۱۳۸۸

برنامه نویسی شیء گرا - قسمت دوم

 بعضي از اشياء ويژگيهايي دارند که فقط حالات خاصي رو ميپذيرند. مثلا شعاع یک توپ نمیتواند 0 يا منفي باشد. ميتوانيم اين محدوديتها را براي هر ويژگي اي  که لازم دارد اعمال کنيم. با همين مثال توپ شروع ميکنيم. اول شعاع توپ را طوري تعريف ميکنيم که فقط موقع تعريف توپ مقدار دهی شود و بعد غير قابل تغيير باشد.
class Ball(object):
    '''represents a ball object'''
  
    def __init__(self,radius):
        #we make radius a private attribute by
        #adding __ at its beginning
        self.__radius=radius
   

    #we call this a getter method for __radius
    def get_radius(self)
        return self.__radius


    #we
make a property read-only by only defining 
    #a getter method for it
    #I also add a docstring for this property
    radius=property(get_radius,

                    doc='''radius of the ball''')
 


>>> myball=Ball(5)
>>> myball.radius
5
>>> myball.radius=6

Traceback (most recent call last):
  File "", line 1, in
    myball.radius=6
AttributeError: can't set attribute
>>>
>>> myball.radius
5
 ما الان یک ویژگی غیر قابل تغییر تعریف کردیم(در اصطلاح یک "ریدونلی پراپرتی")
حالا قابلیت تغییر دادن هم اضافه می کنیم با این محدودیت که شعاع توپ باید مثبت باشد

class Ball(object):

    def __init__(self,radius): self.__radius=radius
   
    def get_radius(self):
        return self.__radius




    #we call this a setter method for __radius
    def set_radius(self,radius):
        if radius>0:
            #if it is a valid value then assign it
            self.__radius=radius
        else:
            #no assignments happen here
            #printing a message to warn user
            print 'can\'t assign this value,',\

                  'radius must be positive'

    #both getter and setter methods are included
    radius=property(get_radius,set_radius)


>>> myball=Ball(5)
>>> myball.radius
5
>>> myball.radius=6
>>> myball.radius
6
>>> myball.radius=-1
can't assign this value, radius must be positive
>>> myball.radius
6
>>> 

اگر دقت کرده باشيد در تابع سازنده ویژگی شعاع رو با __ شروع کرديم. اين باعث ميشود که اين "اتريبوت" پوشيده بماند يعني نميشود بيرون از کلاس تغييرش داد یا حتی مقدارش را گرفت.  ببينيد

>>> myball.__radius
Traceback (most recent call last):
  File "", line 1, in
    myball.__radius
AttributeError: 'Ball' object has no attribute '__radius'
>>>

یکی از ایرادهایی که در در برنامه نویسی شیء گرا به پایتون وارده همین بحث خصوصی سازی ویژگیها و متود هاست. در حقیقت وقتی اسم یک متود یا ویژگی را با __ شروع کنیم پایتون فقط بااسم دیگری ذخیره اش میکند! دقت کنید
>>> myball._Ball__radius
6
>>> myball._Ball__radius=-1
>>> myball.radius
-1
>>>

این به این معنی است که عملا در پایتون همه ی ویژگیها و متود های یک کلاس همگانی (پابلیک) اند
راه قشنگ تری هم برای تعریف پراپرتی ها هست و آن استفاده از "دکوراتور" هاست. اینجا معادل مثال اول را با این روش مینویسیم 
class Ball(object):

    def __init__(self,radius): self.__radius=radius

    @property
    def radius(self):
        '''radius of the ball'''
        return self.__radius 


>>> myball=Ball(5)
>>> myball.radius
5
 
هر پراپرتی میتواند 3 متود "گتر"، "ستر" و "دیلیتر" داشته باشد به علاوه ی یک "داک استرینگ". الان من شعاع توپ را به صورت یک پراپرتی کامل بااستفاده از "دکوراتور" ها تعریف میکنم.

class Ball(object):

    def __init__(self,r): self.__radius=r

    @property
    def radius(self):
        '''radius of the ball'''
        return self.__radius

    @radius.setter
    def radius(self,r):
        if r>0: self.__radius=r
        else: print 'must be positive'

    @radius.deleter
    def radius(self):
        #this method will delete __radius attribute
        #and so will its related property
        del self.__radius
 
>>> myball=Ball(5)
>>> myball.radius=0
must be positive
>>> del myball.radius
>>> myball.radius
Traceback (most recent call last):
  File "", line 1, in
    myball.radius
  File "C:\Users\SEVEN\Desktop\basic oop\basic oop.py", line 55, in radius
    return self.__radius
AttributeError: 'Ball' object has no attribute '_Ball__radius'
>>>

با حذف کردن یک پراپرتی در واقع متود دیلیترش صدا زده میشود.

برای اطلاعات بیشتر در مورد پراپرتی ها به سایت رسمی پایتون اینجا و یا اینجا مراجعه کنید. در ضمن اگه هر سوال یا پیشنهادی هم دارید به صورت نظر به همین پست بفرستید.
موفق باشید ☺



۲ نظر:

  1. هی!
    خوشحالم که یکی هست که به python اهمیت میده و دوسش داره!
    من یه حس نامادرانگی (!) خاصی نسبت بهش دارم...
    یه پروژه ای بود که قرار بود تو این کد بزنیمش که نشد ... یه سری توطئه جلوی کارو گرفت !:دال

    پاسخحذف
  2. :دی مرسی، به نظرم الان پایتون یکی از زبوناییه که هر برنامه نویسی باید یاد بگیره. تو قسمت معرفی کتاب یک بایت از پایتون یه بخش داره "برنامه نویسان چه می گویند؟" که به نظرم اهمیت پایتونو برای هر برنامه نویسی روشن میکنه.

    پاسخحذف