Lompati ke konten utama
Modul 9 · Pelajaran 2 dari 434/36 dalam kursus~12 min
Pelajaran modul (2/4)

dataclass: kelas data tanpa boilerplate

Dekorator @dataclass (modul dataclasses) secara otomatis menghasilkan __init__, __repr__, dan __eq__ untuk kelas yang tugasnya hanya mengadakan data. Lebih sedikit boilerplate, kode lebih jelas.

Tanpa kelas data (boilerplate)

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)

Dengan kelas data

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

Polanya: mendeklarasikan kolom sebagai anotasi kelas (name: type), opsional dengan nilai default. @dataclass menghasilkan sisanya.

Default dan default_pabrik

Python
from dataclasses import dataclass, field

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

beku=Benar: tidak dapat diubah

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

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

Kelas data frozen juga dapat di-hash: Anda dapat menggunakannya sebagai kunci dict atau mengatur elemen.

order=True: perbandingan otomatis

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

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

Menghasilkan __lt__, __le__, __gt__, __ge__ membandingkan bidang dalam urutan mereka diumumkan.

Metode biasa

Kelas data tetap menjadi kelas reguler: Anda dapat menambahkan metode.

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

Kelas data yang tidak dapat diubah dan efisien

Anda dapat membuat kelas data tidak dapat diubah dengan meneruskan argumen frozen=True ke dekorator: @dataclass(frozen=True). Hal ini menimbulkan kesalahan pada setiap upaya untuk mengubah atribut setelah pembuatan instance, sehingga membuat instance aman untuk lingkungan bersamaan atau untuk digunakan sebagai kunci kamus.

Cobalah sendiri

Latihan#python.m9.l2.e1
Upaya: 0Memuat…

Buat kelas data `Buku` dengan bidang `judul: str` dan `halaman: int`. Buat instance sebagai `l = Book('Moby Dick', 635)`. Evaluasi `l == Buku('Moby Dick', 635)`.

Memuat editor…
Tunjukkan petunjuk

@dataclass menghasilkan __eq__ membandingkan bidang demi bidang.

Solusi tersedia setelah 3 upaya

Tinjau latihan

Latihan#python.m9.l2.e2
Upaya: 0Memuat…

Buat kelas data `Keranjang` dengan bidang `item: daftar[str]` dengan default_factory=list. Buat instance `c1 = Basket()` dan `c2 = Basket()`, tambahkan 'mela' ke c1.items. Evaluasi `(c1.items, c2.items)` untuk memverifikasi bahwa daftar tersebut BUKAN sama.

Memuat editor…
Tunjukkan petunjuk

field(default_factory=list) menjamin daftar baru per instance.

Solusi tersedia setelah 3 upaya

Tantangan tambahan

Latihan#python.m9.l2.e3
Upaya: 0Memuat…

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`.

Memuat editor…
Tunjukkan petunjuk

Gunakan @dataclass di atas kelas Point, dan deklarasikan x: float dan y: float.

Solusi tersedia setelah 3 upaya