メインコンテンツにスキップ
モジュール 9 · レッスン 2 / 4コース内の 34/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)

凍結=True: 不変

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

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

frozen データクラスも ハッシュ可能: 辞書キーとして使用できます または要素を設定します。

order=True: 自動比較

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読み込み中…

`title: str` および `pages: int` フィールドを持つデータクラス `Book` を作成します。 `l = Book('Moby Dick', 635)` としてインスタンス化します。 `l == Book('Moby Dick', 635)` を評価します。

エディターを読み込み中…
ヒントを表示

@dataclass はフィールドごとに比較する __eq__ を生成します。

3 回の試行後に解決策が利用可能になります

復習演習

運動#python.m9.l2.e2
試行回数: 0読み込み中…

default_factory=list でフィールド `items: list[str]` を持つデータクラス `Basket` を作成します。 `c1 = Basket()` と `c2 = Basket()` をインスタンス化し、c1.items に 'mela' を追加します。 `(c1.items, c2.items)` を評価して、それらが同じリストではないことを確認します。

エディターを読み込み中…
ヒントを表示

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

エディターを読み込み中…
ヒントを表示

Point クラスの上で @dataclass を使用し、x: float と y: float を宣言します。

3 回の試行後に解決策が利用可能になります