الانتقال إلى المحتوى الرئيسي
الوحدة 9 · الدرس 2 من 434/36 في الدورة~12 min
دروس الوحدة (2/4)

فئة البيانات: فئات البيانات بدون قالب معياري

يقوم مصمم الديكور @dataclass (وحدة dataclasses) تلقائيًا بإنشاء __init__، و__repr__، و__eq__ للفصول الدراسية التي تكون وظيفتها الوحيدة هي **الاحتفاظ البيانات **. نموذج أقل، رمز أكثر وضوحًا.

بدون فئة البيانات (النموذجي)

Python
class Punto:
    def __init__(self, x: float, y: float) -> None:
        self.x = x
        self.y = y
    def __repr__(self) -> str:
        return f"Punto(x={self.x}, y={self.y})"
    def __eq__(self, other) -> bool:
        if not isinstance(other, Punto):
            return NotImplemented
        return (self.x, self.y) == (other.x, other.y)

مع فئة البيانات

Python
from dataclasses import dataclass

@dataclass
class Punto:
    x: float
    y: float

p = Punto(3, 4)
p             # Punto(x=3, y=4)   ← __repr__ gratis
Punto(3, 4) == Punto(3, 4)        # True ← __eq__ gratis
p.x, p.y      # 3, 4

النمط: قم بتعريف الحقول على أنها تعليقات توضيحية للفئة (name: type)، اختياريًا بقيمة افتراضية. @dataclass يُنشئ الباقي.

الافتراضي و default_factory

Python
from dataclasses import dataclass, field

@dataclass
class Articolo:
    nome: str
    prezzo: float = 0.0
    tag: list[str] = field(default_factory=list)

مجمد = صحيح: غير قابل للتغيير

Python
@dataclass(frozen=True)
class Coordinata:
    lat: float
    lon: float

c = Coordinata(45.4, 9.2)
c.lat = 99   # FrozenInstanceError!

فئات البيانات frozen أيضًا قابلة للتجزئة: يمكنك استخدامها كمفاتيح إملاء أو ضبط العناصر

الترتيب = صحيح: المقارنات التلقائية

Python
@dataclass(order=True)
class Voto:
    valore: int

Voto(10) < Voto(20)   # True
sorted([Voto(30), Voto(10), Voto(20)])

يُنشئ __lt__، __le__، __gt__، __ge__ مقارنة الحقول بالترتيب تم الإعلان عنهم.

الطرق العادية

تظل فئات البيانات فئات عادية: يمكنك إضافة طرق.

Python
import math
from dataclasses import dataclass

@dataclass
class Punto:
    x: float
    y: float
    def distanza_dall_origine(self) -> float:
        return math.hypot(self.x, self.y)

Punto(3, 4).distanza_dall_origine()   # 5.0

فئات البيانات غير قابلة للتغيير وفعالة

يمكنك جعل فئة البيانات غير قابلة للتغيير عن طريق تمرير الوسيطة frozen=True إلى مصمم الديكور: @dataclass(frozen=True). يؤدي هذا إلى ظهور خطأ في أي محاولة لتغيير السمات بعد إنشاء مثيل لها، مما يجعل المثيلات آمنة للبيئات المتزامنة أو للاستخدام كمفاتيح القاموس.

جربه بنفسك

تمرين#python.m9.l2.e1
المحاولات: 0جارٍ التحميل…

أنشئ فئة بيانات "كتاب" تحتوي على الحقول "العنوان: str" و"الصفحات: int". قم بإنشاء مثيل له كـ `l = Book('Moby Dick', 635)`. تقييم `l == Book('Moby Dick', 635)`.

جارٍ تحميل المحرر…
إظهار التلميح

يقوم @dataclass بإنشاء __eq__ مقارنة الحقل حسب الحقل.

الحل متاح بعد 3 من المحاولات

تمرين المراجعة

تمرين#python.m9.l2.e2
المحاولات: 0جارٍ التحميل…

قم بإنشاء فئة بيانات `سلة` باستخدام الحقل `العناصر: list[str]` مع default_factory=list. قم بإنشاء مثيل `c1 = Basket()` و`c2 = Basket()`، وألحق "mela" بـ c1.items. قم بتقييم `(c1.items, c2.items)` للتأكد من أنها ليست نفس القائمة.

جارٍ تحميل المحرر…
إظهار التلميح

يضمن الحقل (default_factory=list) قائمة جديدة لكل مثيل.

الحل متاح بعد 3 من المحاولات

التحدي الإضافي

تمرين#python.m9.l2.e3
المحاولات: 0جارٍ التحميل…

Import `dataclass` from `dataclasses`. Create a dataclass `Point` containing two float coordinates `x` and `y`. Instantiate a point with `x=1.5` and `y=2.5` storing it in `p`. Finally, evaluate `p`.

جارٍ تحميل المحرر…
إظهار التلميح

استخدم @dataclass أعلى نقطة الفئة، وأعلن عن x: float وy: float.

الحل متاح بعد 3 من المحاولات