Decorators
@serde
@serde は @serialize と @deserialize デコレータのラッパーです。
以下のコードがあるとします。
@serde
class Foo:
...
上記のコードは、以下のコードと同等です。
@deserialize
@serialize
@dataclass
class Foo:
...
@serde デコレータは以下を行います。
- クラスに
@serializeと@deserializeデコレータを追加します。 - クラスが
@dataclassを持っていない場合、@dataclassデコレータを追加します。 - 両方の(デ)シリアライズ属性をデコレータに渡すことができます。
serializer属性は@deserializeで無視され、deserializer属性は@serializeで無視されます。
@serde(serializer=serializer, deserializer=deserializer)
@dataclass
class Foo:
...
注記:
@serdeは@dataclassデコレータなしで動作します。
これはserdeが@dataclassを自動的に検出し、宣言されたクラスに追加するからです。
しかし@dataclassを定義しない場合、mypy ではToo many argumentsまたはUnexpected keyword argumentというエラーが発生します。これは mypy の制限によるものです。@serde class Foo: ...しかし、PEP681に準拠した型チェッカー(例:pyright)を使用すると、pyserdeが PEP681 dataclass_transform をサポートしているため、型エラーは発生しません。
@serialize と @deserialize
@serialize および @deserialize は内部的に @serde によって使用されます。
以下に該当する場合、これら2つのデコレータを使用することを推奨します。
- シリアライズまたはデシリアライズの機能のみが必要な場合
- 以下のように異なるクラス属性を持つことを望む場合
@deserialize(rename_all = "snakecase")
@serialize(rename_all = "camelcase")
class Foo:
...
上記に当てはまらない場合は @serde の使用を推奨します。
@serde なしでクラスを(デ)シリアライズする
pyserdeは v0.10.0 以降、@serde なしでデータクラスを(デ)シリアライズできます。
この機能は、外部ライブラリで宣言されたクラスを使用したい場合や、@serde デコレータが型チェッカーで機能しない場合に便利です。この例を参照してください。
どのように動作するのでしょうか?
それは非常に単純で、クラスが@serdeデコレータを持っていない場合、pyserdeは @serde デコレータを追加します。
最初のAPI呼び出しには時間がかかるかもしれませんが、生成されたコードは内部的にキャッシュされるため問題にはなりません。
以下にサードパーティパッケージのクラスをデシリアライズする例を示します。
@dataclass
class External:
...
to_dict(External()) # "@serde" なしで動作します
この場合、rename_all などのクラス属性を指定することはできません。
外部のデータクラスにクラス属性を追加したい場合は、データクラスを拡張することでそれを行う方法があります。この例を参照してください。
@dataclass
class External:
some_value: int
@serde(rename_all="kebabcase")
@dataclass
class Wrapper(External):
pass
前方参照をどのように使用するか?
pyserdeは前方参照をサポートしています。
ネストされたクラス名を文字列で置き換えると、pyserdeはネストされたクラスが定義された後にデコレータを探して評価します。
from __future__ import annotations # annotationsをインポート
@dataclass
class Foo:
i: int
s: str
bar: Bar # "Bar" は後で宣言されていても指定できます
@serde
@dataclass
class Bar:
f: float
b: bool
# "Bar" が定義された後に pyserde デコレータを評価します
serde(Foo)
PEP563 Annotationsによる遅延評価
pyserdeは PEP563 Annotationsによる遅延評価をサポートしています。
from __future__ import annotations
from serde import serde
@serde
class Foo:
i: int
s: str
f: float
b: bool
def foo(self, cls: Foo): # 定義される前に "Foo" 型を使用できます
print('foo')
完全な例については examples/lazy_type_evaluation.py を参照してください。