基本¶
cattrs のすべての機能は、cattrs.Converter オブジェクトを通じて公開されます。グローバル・コンバーターは、cattrs.global_converter として便宜上提供されていますが、より複雑なカスタマイズは、プライベート・インスタンスで実行する必要があります。プライベート・インスタンスはいくつでも作成できます。
コンバーターとフック¶
コンバーターのコア機能は、フック と呼ばれる、提供された および カスタム処理関数 を構成することによって、データを構造化および非構造化することです。
プライベート・コンバーターを作成するには、cattrs.Converter をインスタンス化します。コンバーターは比較的安価なので、ユーザーは必要な数だけ持つことをお勧めします。
2 つの主要なメソッド、structure と unstructure は、構造化 データと 非構造化 データの間で変換するために使用されます。
>>> from cattrs import structure, unstructure
>>> from attrs import define
>>> @define
... class Model:
... a: int
>>> unstructure(Model(1))
{'a': 1}
>>> structure({"a": 1}, Model)
Model(a=1)
cattrs には、デフォルトで豊富な un/structuring フックのライブラリが付属していますが、組み込みのフックとカスタム・フックを組み合わせるのに優れています。
カスタマイズへの最も簡単なアプローチは、新しいフックをゼロから作成することです。たとえば、int クラス用に独自のフックを作成し、それをコンバーターに登録できます。
>>> from cattrs import Converter
>>> converter = Converter()
>>> @converter.register_structure_hook
... def int_hook(value, type) -> int:
... if not isinstance(value, int):
... raise ValueError('not an int!')
... return value
これで、int を変換する他のフックはそれを使用します。
カスタマイズへの別のアプローチは、既存のフックを独自の関数でラップ (構成) することです。ベース・フックはコンバーターから取得し、Python が提供する関数合成の非常に豊富なメカニズムに適用できます。
>>> base_hook = converter.get_structure_hook(Model)
>>> @converter.register_structure_hook
... def my_model_hook(value, type) -> Model:
... # Apply any preprocessing to the value.
... result = base_hook(value, type)
... # Apply any postprocessing to the model.
... return result
(cattrs.structure({}, Model) は、cattrs.get_structure_hook(Model)({}, Model) と同等です。)
ここで、このフックを使用して Model を構造化すると、✨関数合成の魔法✨ により、そのフックは古い int_hook を使用します。
>>> converter.structure({"a": "1"}, Model)
+ Exception Group Traceback (most recent call last):
| File "...", line 22, in <module>
| base_hook({"a": "1"}, Model)
| File "<cattrs generated structure __main__.Model>", line 9, in structure_Model
| cattrs.errors.ClassValidationError: While structuring Model (1 sub-exception)
+-+---------------- 1 ----------------
| Traceback (most recent call last):
| File "<cattrs generated structure __main__.Model>", line 5, in structure_Model
| File "...", line 15, in my_int_hook
| raise ValueError("not an int!")
| ValueError: not an int!
| Structuring class Model @ attribute a
+------------------------------------
cattrs のカスタマイズの詳細については、カスタム (非) 構造化 を参照してください。より高度な構造化のカスタマイズは、一般に ストラテジー と呼ばれます。
グローバル・コンバーター¶
cattrs.structure() などのグローバル cattrs 関数は、単一の グローバル・コンバーター を使用します。新しい構造および非構造化フックの登録など、このグローバル・コンバーターに加えられた変更は、グローバル関数を使用するすべてのコードに影響します。
次の関数は、このグローバル・コンバーターを暗黙的に使用します。
グローバル・コンバーターに加えられた変更は、これらの関数の動作に影響します。
大規模なアプリケーションでは、cattrs.Converter の異なるプライベート・インスタンスを作成してカスタマイズすることを強くお勧めします。