web-dev-qa-db-ja.com

Python 3.7:データクラスとSimpleNameSpaceのユーティリティ

Python 3.7では、事前定義された特別な関数を持つ新しいdataclassesが提供されます。

概要の点から、dataclassesSimpleNameSpaceはどちらも、ニースデータカプセル化機能を提供します。

@dataclass
class MyData:
    name:str
    age: int

data_1 = MyData(name = 'JohnDoe' , age = 23)

data_2 = SimpleNameSpace(name = 'JohnDoe' , age = 23)

多くの場合、データをラップして移動するためだけにSimpleNameSpaceを使用します。

私はそれをサブクラス化して特別な機能を追加します:

from types import SimpleNameSpace

class NewSimpleNameSpace(SimpleNameSpace):
    def __hash__(self):
        return some_hashing_func(self.__dict__)

私の質問:

  1. SimpleNameSpacedataclassesのどちらを選択するのですか?
  2. SimpleNameSpaceを拡張しても同じ効果が得られるのに、なぜそれらが必要だったのですか?
  3. 他のすべての使用例dataclassesは何に対応しますか?
16
xssChauhan

簡単に言えば、これはすべて PEP 557 でカバーされます。質問の順序が少し狂っています...

どうして?

  1. PEP 526を利用して、そのようなクラスを定義する簡単な方法を提供する。
  2. 静的型チェッカーをサポートします。

それらをいつ使用するかを選ぶ方法は?

PEPは、それらが代替ではなく、他のソリューションが独自の場所を持つことを期待していることは非常に明確です。

したがって、他の設計上の決定と同様に、気になる機能を正確に決定する必要があります。以下が含まれている場合、データクラスは絶対に必要ありません。

データクラスを使用することが適切ではない場所はどこですか?

タプルまたは辞書とのAPI互換性が必要です。 PEP 484および526で提供されるものを超える型の検証が必要です。または、値の検証または変換が必要です。

そうは言っても、SimpleNameSpaceについても同じことが言えるので、他に何を見れば判断できるでしょうか。データクラスによって提供される追加機能を詳しく見てみましょう...

SimpleNameSpaceの既存の定義は次のとおりです。

名前空間への属性アクセスと、意味のあるreprを提供する単純なオブジェクトサブクラス。

python docs次に、シンプルな__init____repr__および__eq__実装。これをPEP 557と比較すると、データクラスには次のオプションもあります。

  • 順序付け-クラスをそのフィールドのタプルであるかのように順番に比較します。
  • 不変性-フィールドに割り当てると例外が生成されます
  • ハッシュの制御-これはお勧めできません。

明らかに、順序付けや不変性を気にする場合(またはニッチなハッシュ制御が必要な場合)は、データクラスを使用する必要があります。

他の使用例?

私が見ることはできませんが、最初の「なぜ?」他のユースケースをカバーします。

5
Peter Brittain

DataclassesはnamedtupleよりもSimpleNamespaceおよび人気のある attrs パッケージに似ています(これは PEP でさえ言及されていません)。彼らは2つの異なる意図された目的を果たします。

データクラス

  • 構造化された
  • 入力(デフォルトでは、オプション)
  • 基本的なdunderメソッドの定型文のほとんどを書き込みます(___init___、___hash___、___eq___など)
  • 属性のデフォルト値の簡単なメカニズムを提供する
  • ___slots___とメソッドを簡単に追加できます

SimpleNamespace

  • 「グラブバッグ」のデータ構造
  • 辞書よりもクラスが少ない場合に使用
  • ___slots___のようなものを使用することを意図していません

SimpleNamespaceドキュメントから:

SimpleNamespaceは、_class NS: pass_の代わりとして役立ちます。ただし、構造化レコードタイプの場合は、代わりにnamedtuple()を使用してください。

_@dataclass_はnamedtupleの多くのユースケースを置き換えることになっているため、名前付きレコード/構造体はSimpleNamespaceではなく_@dataclass_で実行する必要があります。

また、 このPyConのレイモンドヘッティンガーによる講演 を参照することもできます。この場合、彼は_@dataclass_のバックストーリーに入り、それを使用しています。

8
Edward Minnix