1. ホーム
  2. パイソン

[解決済み】データクラスとは何ですか、一般的なクラスとどう違うのですか?

2022-03-28 21:48:42

質問

PEP 557 データクラスがPythonの標準ライブラリに導入されました。

これらは @dataclass デコレータで、それらは "mutable namedtuples with default" であるとされていますが、これが実際に何を意味するのか、一般的なクラスとどう違うのか、私はよく理解していません。

Pythonのデータクラスとは一体何なのか、また、いつ使うのがベストなのか?

どのように解決するのですか?

データクラスは、多くのロジックを含むのではなく、状態を保存することに特化した通常のクラスです。ほとんどが属性で構成されるクラスを作成するたびに、データクラスが作成されます。

の内容 dataclasses モジュールが行うのは より簡単に データクラスを作成することができます。これは多くの定型句を処理してくれます。

これは、データクラスがハッシュ化可能でなければならない場合に特に有用です。 __hash__ メソッドと同様に __eq__ メソッドを使用します。もし、カスタムの __repr__ メソッドは、デバッグを容易にするために、非常に冗長になることがあります。

class InventoryItem:
    '''Class for keeping track of an item in inventory.'''
    name: str
    unit_price: float
    quantity_on_hand: int = 0

    def __init__(
            self, 
            name: str, 
            unit_price: float,
            quantity_on_hand: int = 0
        ) -> None:
        self.name = name
        self.unit_price = unit_price
        self.quantity_on_hand = quantity_on_hand

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand
    
    def __repr__(self) -> str:
        return (
            'InventoryItem('
            f'name={self.name!r}, unit_price={self.unit_price!r}, '
            f'quantity_on_hand={self.quantity_on_hand!r})'

    def __hash__(self) -> int:
        return hash((self.name, self.unit_price, self.quantity_on_hand))

    def __eq__(self, other) -> bool:
        if not isinstance(other, InventoryItem):
            return NotImplemented
        return (
            (self.name, self.unit_price, self.quantity_on_hand) == 
            (other.name, other.unit_price, other.quantity_on_hand))

dataclasses に減らすことができます。

from dataclasses import dataclass

@dataclass(unsafe_hash=True)
class InventoryItem:
    '''Class for keeping track of an item in inventory.'''
    name: str
    unit_price: float
    quantity_on_hand: int = 0

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand

同じクラス・デコレーターで、比較メソッドも生成できます ( __lt__ , __gt__ など)、イミュータビリティを扱う。

namedtuple クラスもデータクラスですが、デフォルトでイミュータブルです(シーケンスであると同時に)。 dataclasses は、この点ではるかに柔軟性があり、以下のような構造を簡単に作成することができます。 と同じ役割を果たします。 namedtuple クラス .

このPEPは attrs プロジェクト は、さらに多くのこと(スロット、バリデータ、コンバータ、メタデータなどを含む)を行うことができます。

もし、いくつかの例を見たいのであれば、私は最近 dataclasses を、私のいくつかの コードの冒険 の解決策をご覧ください。 7日目 , 8日目 , 11日目 そして 20日目 .

を使いたい場合は dataclasses モジュールのインストールは、Python のバージョン < 3.7 では バックポートモジュール (3.6が必要) または attrs プロジェクトに参加しています。