کتابخانه dataclasses در پایتون
کتابخانه dataclasses که از پایتون 3.7 بهطور رسمی اضافه شد، برای تعریف کلاسهایی طراحی شده که عمدتاً نگهدارنده داده (data containers) هستند. با استفاده از دکوراتور @dataclass میتوان کد تکراری مثل سازنده (__init__)، نمایشی خواندنی (__repr__)، و توابع مقایسه را بهصورت خودکار تولید کرد. این کتابخانه ساده، خوانایی و سرعت توسعه را افزایش میدهد و در کاربردهای مثل DTOها، پیکربندیها و سریالسازی بسیار مفید است.
مثال ساده
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int = 0
active: bool = True
p = Person("Ali", 30)
print(p) # Person(name='Ali', age=30, active=True)در این مثال، @dataclass بهصورت خودکار متد __init__ و __repr__ و __eq__ را میسازد. این کار باعث میشود کد خواناتر و کوتاهتر باشد.
پارامترهای مهم دکوراتور
| پارامتر | توضیح | مقدار پیشفرض |
|---|---|---|
| init | تولید __init__ یا خیر | True |
| repr | تولید __repr__ | True |
| eq | تولید __eq__ برای مقایسهٔ اشیاء | True |
| order | تولید متدهای مرتبسازی (__lt__, __gt__, …) | False |
| frozen | ایمنسازی داده — غیرقابل تغییر کردن نمونه | False |
| slots | استفاده از __slots__ برای کاهش حافظه و افزایش سرعت | False (Python ≥ 3.10) |
پیشفرضهای قابل اشتباه: default_factory و دادههای قابل تغییر
from dataclasses import dataclass, field
from typing import List
@dataclass
class Team:
name: str
members: List[str] = field(default_factory=list)
t1 = Team("A")
t1.members.append("Ali")
t2 = Team("B")
print(t2.members) # [] — safe because default_factory ساخته میشوداستفاده از لیست یا دیکشنری بهعنوان مقدار پیشفرض مستقیم اشتباه است چون یک شیء مشترک بین همهٔ نمونهها میشود. برای جلوگیری از این مشکل از field(default_factory=...) استفاده کنید تا هر نمونه یک شیء جدید بگیرد.
مثال: کلاسهای ایمن (frozen) و ایجاد نسخهٔ جدید
from dataclasses import dataclass, replace
@dataclass(frozen=True)
class Config:
host: str
port: int
c1 = Config("localhost", 8000)
# c1.port = 8080 # خطا: تغییر در dataclass منجمد امکانپذیر نیست
c2 = replace(c1, port=8080)
print(c1, c2)با frozen=True نمونهها غیرقابل تغییر میشوند. برای ساختن نسخهای جدید با اندکی تغییر، از تابع replace استفاده میکنیم که یک شیء جدید با مقادیر جایگزین شده برمیگرداند.
اعتبارسنجی بعد از مقداردهی: __post_init__
from dataclasses import dataclass
@dataclass
class Product:
name: str
price: float
def __post_init__(self):
if self.price < 0:
raise ValueError("price must be non-negative")متد __post_init__ بلافاصله بعد از ساخت نمونه و اجرای __init__ اجرا میشود. برای اعتبارسنجی، تبدیل دادهها یا مقداردهی مشتق شده از این متد استفاده کنید.
سریالسازی سریع: asdict و astuple
from dataclasses import asdict, astuple
p = Person("Sara", 25)
print(asdict(p)) # {'name': 'Sara', 'age': 25, 'active': True}
print(astuple(p)) # ('Sara', 25, True)توابع asdict و astuple بهسرعت یک نمونهٔ dataclass را به دیکشنری یا تاپل تبدیل میکنند که برای سریالسازی یا لاگگیری مفید است. توجه داشته باشید که این توابع بهصورت بازگشتی برای dataclassهای تو در تو عمل میکنند.
ویژگی های پیشرفته و کاربردهای عملی
- slots=True (از پایتون 3.10): کاهش حافظه و سرعت دسترسی بهتر برای تعداد زیاد نمونهها.
- order=True: اضافه کردن مرتبسازی طبیعی بر اساس ترتیب فیلدها.
- استفاده در DTO، خواندن/نوشتن کانفیگ، تبدیل به JSON و تعامل با فریمورکهایی مثل FastAPI یا کتابخانههای سریالسازی.
- ترکیب با typing برای گرفتن مزایای نوعدهی استاتیک و تکمیل اتوماتیک در IDEها.
نمونه: استفادهٔ بهینه با slots و typing
from dataclasses import dataclass
from typing import List
@dataclass(slots=True)
class Point:
x: float
y: float
@dataclass(slots=True)
class Polygon:
vertices: List[Point]استفاده از slots=True میتواند مصرف حافظه را کم کند و سرعت دسترسی به attributes را افزایش دهد. این گزینه برای ساختارهایی با هزاران نمونه بسیار مفید است. توجه کنید که پشتیبانی کامل slots از پایتون 3.10 به بعد بهتر است.
بهترین شیوهها و نکات نهایی
- برای مقادیر پیشفرض قابل تغییر از
field(default_factory=...)استفاده کنید. - اگر میخواهید اشیاءimmutable باشند، از
frozen=Trueبهره ببرید و برای تغییرات ازreplaceاستفاده کنید. - در برنامههای حجیم با تعداد زیاد نمونه،
slots=Trueرا بررسی کنید تا مصرف حافظه کاهش یابد. - برای اعتبارسنجی یا تبدیلهای پس از مقداردهی از
__post_init__استفاده کنید. - اگر نیاز به کنترل دقیقتری روی سریالسازی/ولید دارید، dataclasses را با کتابخانههایی مثل marshmallow یا pydantic مقایسه کنید؛ dataclasses ساده، سبک و مناسب برای بیشتر نیازهاست.
کتابخانهٔ dataclasses راهی ساده و قدرتمند برای مدیریت کلاسهای نگهدارندهٔ داده در پایتون فراهم میکند. با رعایت چند قاعدهٔ ساده (استفاده از default_factory برای دادههای قابل تغییر، بهکارگیری frozen برای ایمنی، و در صورت نیاز فعالسازی slots) میتوانید کدی تمیزتر، سریعتر و ایمنتر بنویسید.
آیا این مطلب برای شما مفید بود ؟




