שיעורי מודול (2/4)
dataclass: מחלקות נתונים ללא לוחית
הדקורטור @dataclass (מודול dataclasses) יוצר אוטומטית
__init__, __repr__ ו__eq__ עבור כיתות שתפקידן היחיד הוא להחזיק
נתונים. פחות לוחית, קוד ברור יותר.
ללא dataclass (לוחית)
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)עם dataclass
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 ו-default_factory
from dataclasses import dataclass, field
@dataclass
class Articolo:
nome: str
prezzo: float = 0.0
tag: list[str] = field(default_factory=list)frozen=נכון: בלתי משתנה
@dataclass(frozen=True)
class Coordinata:
lat: float
lon: float
c = Coordinata(45.4, 9.2)
c.lat = 99 # FrozenInstanceError!frozen מחלקות נתונים הן גם ניתנות לגיבוש: אתה יכול להשתמש בהן כמפתחות dict
או להגדיר אלמנטים.
order=True: השוואות אוטומטיות
@dataclass(order=True)
class Voto:
valore: int
Voto(10) < Voto(20) # True
sorted([Voto(30), Voto(10), Voto(20)])יוצר __lt__, __le__, __gt__, __ge__ השוואת שדות בהזמנה
הם הוכרזו.
שיטות רגילות
מחלקות נתונים נשארות מחלקות רגילות: אתה יכול להוסיף שיטות.
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). זה מעלה שגיאה בכל ניסיון לשנות תכונות לאחר מופע, מה שהופך מופעים לבטוחים עבור סביבות במקביל או לשימוש כמפתחות מילון.
נסה זאת בעצמך
צור מחלקת נתונים `ספר` עם השדות `כותרת: str` ו`עמודים: int`. הצג אותו בתור `l = Book('Moby Dick', 635)`. הערך את `l == Book('Moby Dick', 635)`.
הצג רמז
@dataclass יוצר __eq__ השוואה בין שדה לשדה.
הפתרון זמין לאחר 3 ניסיונות
סקירת התרגיל
צור מחלקת נתונים `Basket` עם השדה `items: list[str]` עם default_factory=list. בצע מופע של `c1 = Basket()` ו-`c2 = Basket()`, הוסף את 'mela' ל-c1.items. הערך את `(c1.items, c2.items)` כדי לוודא שהם אינם אותה רשימה.
הצג רמז
field(default_factory=list) מבטיח רשימה חדשה לכל מופע.
הפתרון זמין לאחר 3 ניסיונות
אתגר נוסף
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 מעל המחלקה Point, והכריז על x: float ו-y: float.
הפתרון זמין לאחר 3 ניסיונות