Rozdział 14 · Tworzenie rzeczywistych obiektów

dataclasses

Klasy, które głównie przechowują dane, nie muszą zapisywać __init__ i __repr__ ręcznie.

Mniej szablonowego kodu dla klas danych

Zajęcia takie jak Tochka z sekcji 14.22 – głównie Kod szablonowy: __init__który po prostu kopiuje parametry do self, plus __str__ oraz __eq__prawie zawsze wyglądają tak samo. Moduł dataclasses potrafi wygenerować to wszystko automatycznie:

Dane klasowe: ręcznie i @dataclass
Klasa Normalna
class Tochka:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Tochka(x={self.x}, y={self.y})"

    def __eq__(self, other):
        return self.x == other.x and self.y == other.y
S @dataclass
from dataclasses import dataclass

@dataclass
class Tochka:
    x: int
    y: int
#__init__, __repr__ i __eq__ są generowane automatycznie
Co używać dzisiaj: @dataclass — tam, gdzie klasa głównie PRZECHOWUJE dane i nie korzysta z ręcznej kontroli nad __init__/__repr__/__eq__. Wciąż jest to zwykła klasa — metody dodaje się do ciała dokładnie tak samo jak zawsze.
dataclass_s_metodom.py
from dataclasses import dataclass

@dataclass
class Tochka:
    x: int
    y: int

    def rasstoyanie_do(self, other):
        return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5

a = Tochka(0, 0)
b = Tochka(3, 4)
print(a)                    # Tochka(x=0, y=0) – __repr__ już gotowy
print(a.rasstoyanie_do(b))   # 5.0
Powszechne nieporozumienie: "dataclass nie jest prawdziwą klasą" albo "nie da się pisać metod w dataclass"
Obie są błędne. @dataclass jest zwykłym dekoratorem klas: tylko DODAJE automatycznie generowane __init__, __repr__, __eq__ na zwykłej klasie. Metody, property i wszystko, co można napisać w zwykłej klasie, jest napisane w ten sam sposób w dataclass.
Debug Lab 13: Zmienna domyślność w dataclass
izmenyaemoe_polei_umolchanie.py
from dataclasses import dataclass

@dataclass
class Korzina:
    tovary: list = []   # wygląda jak pułapka z sekcji 14.8!
Traceback (most recent call last):
ValueError: mutable default  for field tovary is not allowed: use default_factory
Co widać na ekranie

Python dataclasses CELOWO wyłącza domyślne prawo do zmiany w adnotacji – to takie samo ryzyko współdzielonej listy dla wszystkich obiektów jak w sekcji 14.8, z tą różnicą, że dataclass jest to wykrywane natychmiast, przez błąd definicji klasy, a nie cichy błąd w czasie działania.

Poprawiony kod
s_default_factory.py
from dataclasses import dataclass, field

@dataclass
class Korzina:
    tovary: list = field(default_factory=list)   # nowy lista dla KAŻDEGO obiektu
Praktyka: dataclasses
interaktywny laptop bezpośrednio w przeglądarce – Python 3.14 przez Pyodide, bez instalacji
Otwórz praktykę →