المستوى المطلوب: مبتدئ
Dataclasses في Python: استبدل 30 سطر boilerplate بـ 3 سطور
لو بتكتب class في Python عشان تخزّن بيانات بس - زي User أو Product أو Order - إنت مضطر تكتب __init__ و __repr__ و __eq__ يدويًا. Dataclasses في Python 3.7+ بتولّدهم تلقائيًا من الـ type hints بـ decorator واحد، فبتنزّل 20 سطر boilerplate لـ 4 سطور بدون ما تخسر أي وظيفة، وبصفر overhead في الـ runtime تقريبًا.
المشكلة باختصار
افترض إن عندك class اسمه User فيه ثلاث fields: id و name و email. الكود الكلاسيكي عشان يبقى كامل بيبقى كده:
class User:
def __init__(self, id, name, email):
self.id = id
self.name = name
self.email = email
def __repr__(self):
return f"User(id={self.id!r}, name={self.name!r}, email={self.email!r})"
def __eq__(self, other):
if not isinstance(other, User):
return NotImplemented
return (self.id, self.name, self.email) == (other.id, other.name, other.email)
def __hash__(self):
return hash((self.id, self.name, self.email))20 سطر، 3 منهم محتوى فعلي والـ 17 الباقيين تكرار. ولو ضيفت field رابع (مثلاً created_at)، لازم تعدّل في 5 أماكن مختلفة. مكان واحد بس لو نسيته، الـ __eq__ هيرجّع نتيجة غلط بدون ما يرمي خطأ - وده bug صعب يتمسك في المراجعة.
مثال للمبتدئ: نموذج طلب الفيزا
تخيّل إنك بتروح السفارة عشان تطلب فيزا. الموظف بيدّيك ورقة فيها خانات جاهزة: الاسم، الجنسية، تاريخ الميلاد، رقم الباسبور. الورقة دي قالب مطبوع، إنت بس بتملا الفراغات. لو الموظف كان مضطر يكتب الورقة بالقلم في كل مرة من الصفر، كان هيكتب نفس الكلام 200 مرة في اليوم، وأي غلط إملائي بسيط بيعمل مشكلة.
الـ Dataclass بتشتغل بنفس الفكرة بالظبط. إنت بتقول للـ Python "النموذج بتاعي فيه الـ fields دي" والـ Python بيولّد كل اللي يخص النموذج (الـ __init__ و __repr__ و __eq__) تلقائيًا. إنت بتكتب الجزء المتغيّر بس، وسايب الكلام المتكرر للـ Python يطبعه ليك.
التعريف العلمي: ما هو الـ Dataclass
الـ Dataclass، حسب PEP 557 اللي اتقبل في يونيو 2018، هو decorator على class بيقرا الـ type annotations الموجودة في الـ class body ويولّد الـ dunder methods الأساسية تلقائيًا: __init__، ، ، وأحيانًا و حسب الإعداد. اتضاف للـ standard library في Python 3.7 (يونيو 2018) واتطوّر في 3.10 بإضافة و .