خانه / آموزش‌ها / آموزش Dataclasses در پایتون

آموزش Dataclasses در پایتون

🐍 HomeOfPython
|
📅 1404/10/19

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

در برنامه‌نویسی شی‌گرا با پایتون، اغلب کلاس‌هایی می‌سازیم که تنها وظیفه‌شان نگهداری داده‌هاست. در روش سنتی، ما مجبور بودیم متدهای __init__، __repr__ و __eq__ را به صورت دستی بنویسیم که باعث ایجاد کدهای تکراری (Boilerplate) می‌شد.

ماژول dataclasses که در پایتون ۳.۷ معرفی شد، این فرآیند را خودکار می‌کند.

۱. مشکل روش سنتی vs راه حل Dataclass

در روش قدیمی، برای یک کلاس ساده باید کد زیادی می‌نوشتیم. دکوریتور @dataclass به صورت خودکار متدهای لازم را برای ما تولید می‌کند.

مقایسه کلاس معمولی و دیتاکلس

python
# (Static) روش قدیمی و طولانی
class Product:
    def __init__(self, name, price, count):
        self.name = name
        self.price = price
        self.count = count
        
    def __repr__(self):
        return f"Product(name={self.name}, price={self.price}, count={self.count})"
Python

۲. مقادیر پیش‌فرض (Default Values)

شما می‌توانید مانند توابع معمولی، برای فیلدها مقدار پیش‌فرض تعیین کنید. توجه داشته باشید که فیلدهای دارای مقدار پیش‌فرض باید بعد از فیلدهای بدون مقدار پیش‌فرض بیایند.

Python
python
# (Static) کد زیر خطا می‌دهد (نکته مهم)
# فیلد بدون مقدار پیش‌فرض (email) نباید بعد از فیلد دارای مقدار پیش‌فرض (is_active) بیاید
@dataclass
class BrokenUser:
    is_active: bool = True
    email: str  # SyntaxError

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

در سطح حرفه‌ای، دیتاکلس‌ها امکانات قدرتمندی برای مدیریت داده‌های تغییرپذیر (Mutable)، اعتبارسنجی بعد از ساخت شیء و ایجاد کلاس‌های غیرقابل تغییر (Immutable) ارائه می‌دهند.

۱. تابع field و مشکل Mutable Defaults

در پایتون، هرگز نباید از لیست یا دیکشنری خالی به عنوان مقدار پیش‌فرض مستقیم استفاده کرد (چون بین تمام نمونه‌ها اشتراک‌گذاری می‌شود). در دیتاکلس‌ها برای حل این مشکل از field(default_factory=...) استفاده می‌کنیم.

Python

۲. متد __post_init__

گاهی نیاز داریم بلافاصله پس از ساخته شدن شیء، محاسباتی انجام دهیم یا داده‌ها را اعتبارسنجی کنیم. از آنجا که __init__ توسط دیتاکلس ساخته می‌شود، ما از __post_init__ استفاده می‌کنیم که به صورت خودکار در انتهای __init__ صدا زده می‌شود.

Python

۳. کلاس‌های Immutable (فریز شده)

اگر می‌خواهید کلاسی بسازید که پس از مقداردهی اولیه، اطلاعات آن قابل تغییر نباشد (Read-only)، می‌توانید از پارامتر frozen=True استفاده کنید. این کار آبجکت را Hashable کرده و می‌توان از آن به عنوان کلید دیکشنری استفاده کرد.

Python

۴. تبدیل به دیکشنری و تاپل

ماژول dataclasses توابع کمکی asdict و astuple را برای سریالایز کردن داده‌ها (مثلاً برای ذخیره در JSON) فراهم می‌کند.

Python