property در پایتون – به زبان ساده
در این مطلب، مفهوم property در پایتون برای استفاده از getters و setters همراه با ارائه مثال و کدهای نمونه، آموزش داده میشود.

property در پایتون
چرا به قابلیت property در پایتون نیاز است؟
میتوان شیئی از این کلاس را ساخت و خصیصه temperature را همانطور که انتظار میرود دستکاری کرد. کد زیر را در این راستا میتوان در شل پایتون اجرا کرد.
>>> # create new object >>> man = Celsius() >>> # set temperature >>> man.temperature = 37 >>> # get temperature >>> man.temperature 37 >>> # get degrees Fahrenheit >>> man.to_fahrenheit() 98.60000000000001
جایگاههای اعشاری اضافی هنگام تبدیل به فارنهایت به دلیل خطای محاسبات ممیز شناور برای عدد قرار میگیرند. هر زمان که هرگونه خصیصهای مانند temperature، همانطور که در بالا نشان داده شده تخصیص داده و یا بازیابی میشود پایتون آن را در شی __dict__ دیکشنری جستجو میکند.
>>> man.__dict__
{'temperature': 37}
دریافت Getters و Setters
یک راهکار واضح برای اعمال محدودیت بالا، مخفیسازی خصیصه temperature (آن را خصوصی میکند) و تعریف یک رابط getter و setter جدید برای دستکاری آن است. این کار به صورت زیر قابل انجام است.
میتوان در کد بالا مشاهده کرد که متدهای ()get_temperature و ()set_temperature تعریف شدهاند و علاوه بر آن، temperature با temperature_ جایگزین شده است. یک زیرخط (_) در آغاز برای تعریف متغیرهای خصوصی (Private) در پایتون مورد استفاده قرار میگیرد.
>>> c = Celsius(-277) Traceback (most recent call last): ... ValueError: Temperature below -273 is not possible >>> c = Celsius(37) >>> c.get_temperature() 37 >>> c.set_temperature(10) >>> c.set_temperature(-300) Traceback (most recent call last): ... ValueError: Temperature below -273 is not possible
در این به روز رسانی، محدودیتهای جدید بیان شده پیرامون درجه حرارت به طور موفقیتآمیزی پیادهسازی شدهاند. پس از این، امکان تنظیم درجه حرارت زیر ۲۷۳- وجود ندارد. شایان توجه است که متغیرهای خصوصی واقعا در پایتون وجود ندارد و برای پیادهسازی آنها قواعد سادهای وجود دارد که باید از آنها پیروی کرد. خود زبان پایتون، هیچ محدودیتی را پیادهسازی نمیکند.
اما پیادهسازی این کد و اعمال این محدودیت به کد حقیقتا مسئله مهمی محسوب نمی شود. مساله اصلی در به روز رسانی بالا آن است که همه افرادی که پیش از این از کلاس درجه حرارت در برنامه خود استفاده کردهاند، باید کد خود را از obj.temperature به ()obj.get_temperature و همه تخصیصهای obj.temperature = val را به (obj.set_temperature(val تغییر دهند. این «بازسازی کد» (Refactoring) میتواند موجب مشکلات زیادی برای مشتریانی بشود که صدها و هزاران خط کد دارند. به طور کلی، به روز رسانی جدیدی که انجام میشود به طور عقبگرد سازگار نیست. در چنین شرایطی است که قابلیت property در پایتون به میان میآید.
کلاس property در پایتون
راهکار پایتون برای سر و کله زدن با مسئله بالا استفاده از property است. در ادامه، روش انجام این کار بیان شده است.
پس از اجرای کد بالا، دستور زیر را باید در شل اجرا کرد.
>>> c = Celsius()
یک تابع ()print درون ()get_temperature و ()set_temperature قرار داده شده است تا به وضوح مشاهده شود که این توابع اجرا شدهاند. آخرین خط از کد، شیئ property یعنی temperature را ایجاد میکند. به سادگی، قابلیت property در پایتون کدهایی را (get_temperature و set_temperature) به دسترسیهای خصیصه عضو (temperature) اضافه میکند. هر کدی که مقدار temperature را بازیابی میکند، به طور خودکار، ()get_temperature را به جای جستوجو در دیکشنری (__dict__)، فراخوانی میکند. این یک ویژگی فوقالعاده در پایتون است. میتوان در بالا مشاهده کرد که ()set_temperature حتی هنگامی که یک شیئ ساخته شده، فراخوانی میشود.
شرحی بر عملکرد property در پایتون
دلیل آنچه در بالا بیان شد آن است که وقتی یک شیئ ساخته میشود، متد ()__init__ فراخوانی میشود. این متد دارای خط self.temperature = temperature است. این تخصیص به طور خودکار ()set_temperature را فراخوانی کرده است.
>>> c.temperature Getting value 0
به طور مشابه، هر دسترسی مانند c.temperature، به طور خودکار ()get_temperature را فراخوانی میکند. این همان کاری است که property انجام میدهد. در ادامه، چندین مثال ارائه شده است.
با استفاده از property، میتوان مشاهده کرد که کلاس ویرایش شده و مقدار محدودیت را بدون نیاز به اعمال هر گونه تغییری در کل مشتری، اعمال کرده است. بدین ترتیب، پیادهسازی کنونی دارای «سازگاری عقبرو» (Backward Compatible) است و همه را راضی خواهد کرد. در نهایت، توجه به این نکته لازم است که مقدار کنونی درجه حرارت در متغیر خصوصی temperature_ ذخیره شده است. خصیصه temperature، یک شیئ property است که رابطی را برای این متغیر خصوصی فراهم میکند.
نگاهی عمیقتر به property
property(fget=None, fset=None, fdel=None, doc=None)
>>> property() <property object at 0x0000000003239B38>
یک شیئ property دارای سه متد ()setter() ،getter و ()deleter برای تعریف fset ،fget و fdel در نهایت است. این یعنی خط کد زیر،
temperature = property(get_temperature,set_temperature)
را میتوان به صورت زیر شکست.
پیادهسازی بالا، ساده است و برای ساخت Propertyها توصیه میشود.
مطالب مجله فرادرس را در جستجوی گوگل سریعتر ببینید













@ که در مثال استفاده شده برای چیست؟