خانه / آموزش‌ها / آموزش Property در پایتون (مدیریت ویژگی‌ها)

آموزش Property در پایتون (مدیریت ویژگی‌ها)

🐍 HomeOfPython
|
📅 1404/10/22

سطح مقدماتی (Beginner Level)

در برنامه‌نویسی شی‌گرا (OOP)، یکی از اصول مهم کپسوله‌سازی (Encapsulation) است؛ یعنی محدود کردن دسترسی مستقیم به متغیرهای داخلی یک کلاس.

در زبان‌های قدیمی‌تر مثل جاوا، برای خواندن یا تغییر یک متغیر از متدهای get_variable() و set_variable() استفاده می‌شد. اما در پایتون، ما از ابزاری قدرتمند و تمیزتر به نام Property استفاده می‌کنیم.

چرا از Property استفاده کنیم؟

فرض کنید یک کلاس دارید که سن کاربر را ذخیره می‌کند. اگر کاربر عدد منفی وارد کند چه می‌شود؟

  1. دسترسی مستقیم (بد): هیچ کنترلی روی داده ورودی ندارید.
  2. متد Getter/Setter (روش قدیمی): کد را شلوغ و خوانایی را کم می‌کند.
  3. Property (روش پایتونیک): هم ظاهر کد ساده است (مثل دسترسی مستقیم) و هم منطق اعتبارسنجی اجرا می‌شود.

تعریف Getter و Setter

با استفاده از دکوریتور @property می‌توانیم یک متد را طوری تعریف کنیم که مثل یک ویژگی (Attribute) رفتار کند.

  1. @property: برای خواندن مقدار (Getter).
  2. @name.setter: برای مقداردهی (Setter).
Python

ویژگی‌های فقط خواندنی (Read-Only)

اگر فقط @property را تعریف کنید و بخش .setter را ننویسید، آن ویژگی غیرقابل تغییر می‌شود. این برای مقادیری که محاسبه می‌شوند (مثل مساحت) عالی است.

Python
python
# Static Snippet: Syntax structure
class MyClass:
    @property
    def my_var(self):
        # Logic to retrieve
        pass
    
    @my_var.setter
    def my_var(self, value):
        # Logic to set/validate
        pass

سطح پیشرفته (Professional Level)

در سطح حرفه‌ای، property فراتر از یک سینتکس ساده است. درک نحوه کارکرد آن در سطح کلاس و تعامل آن با Descriptorها، مدیریت حافظه و Deleterها ضروری است.

حذف ویژگی (Deleter)

مشابه Getter و Setter، می‌توانید یک deleter تعریف کنید که هنگام اجرای دستور del object.attribute فراخوانی شود. این برای پاکسازی منابع (مثل بستن فایل یا کانکشن دیتابیس) هنگام حذف یک ویژگی مفید است.

Python

استفاده از تابع property() (روش کلاسیک)

دکوریتورها صرفاً "Syntactic Sugar" هستند. در پایتون می‌توان property را مستقیماً به عنوان یک تابع در کلاس صدا زد. این روش در کدهای قدیمی یا زمانی که می‌خواهید ویژگی‌ها را به صورت داینامیک بسازید کاربرد دارد.

سینتکس: property(fget, fset, fdel, doc)

Python

نکات فنی و Best Practiceها

  1. هزینه محاسباتی (Computed Properties): اگر منطق داخل @property سنگین است (مثل کوئری دیتابیس)، بهتر است آن را کش (Cache) کنید یا از یک متد معمولی استفاده کنید تا برنامه‌نویس بداند که اجرای آن هزینه‌بر است. دسترسی به Attribute معمولاً باید سریع (O(1)) باشد.
  2. ارث‌بری (Inheritance): پراپرتی‌ها ارث‌بری می‌شوند، اما اگر بخواهید فقط Setter را در کلاس فرزند تغییر دهید، سینتکس کمی پیچیده می‌شود (@ParentClass.attr.setter).
  3. Naming Convention: متغیر واقعی که داده را نگه می‌دارد معمولاً با یک آندرلاین شروع می‌شود (self._x) تا با نام پراپرتی (x) تداخل پیدا نکند و نشان‌دهنده "محافظت شده" بودن آن باشد.
python
# Advanced Snippet: Abstract Property
from abc import ABC, abstractmethod

class Base(ABC):
    @property
    @abstractmethod
    def value(self):
        """باید در کلاس فرزند پیاده‌سازی شود"""
        pass