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)
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
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, 4Polanya: mendeklarasikan kolom sebagai anotasi kelas (name: type),
opsional dengan nilai default. @dataclass menghasilkan sisanya.
Default dan default_pabrik
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
@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
@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.
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.0Kelas 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
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)`.
Tunjukkan petunjuk
@dataclass menghasilkan __eq__ membandingkan bidang demi bidang.
Solusi tersedia setelah 3 upaya
Tinjau latihan
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.
Tunjukkan petunjuk
field(default_factory=list) menjamin daftar baru per instance.
Solusi tersedia setelah 3 upaya
Tantangan tambahan
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`.
Tunjukkan petunjuk
Gunakan @dataclass di atas kelas Point, dan deklarasikan x: float dan y: float.
Solusi tersedia setelah 3 upaya