Class Attributes¶
クラス属性は、クラスの(デ)シリアライズの動作をカスタマイズするために serialize / deserialize デコレータの引数として指定できます。
フィールドをカスタマイズしたい場合は、フィールド属性の使用を検討してください。
クラス属性は全フィールドに影響するため、命名規則やタグ付けなどクラス全体に共通する挙動に向いています。
dataclassesの属性¶
frozen¶
dataclassの frozen クラス属性は期待通りに機能します。
kw_only¶
バージョン0.12.2で新規追加。dataclassの kw_only クラス属性は期待通りに機能します。
完全な例については、examples/kw_only.pyを参照してください。
pyserdeの属性¶
rename_all¶
rename_all を使うと、フィールド名を指定されたケーススタイルに変換できます。
以下の例では、キャメルケースのフィールド名をスネークケースに変換しています。
ケーススタイルの変換処理は python-casefy パッケージに依存しています。
サポートされるケーススタイルの一覧は python-casefy のドキュメントを参照してください。
@serde(rename_all = 'camelcase')
class Foo:
int_field: int
str_field: str
f = Foo(int_field=10, str_field='foo')
print(to_json(f))
上記のコードを実行すると、int_field は intField に、str_field は strField に変換されます。
Note
rename_all クラス属性と rename フィールド属性が同時に使用される場合、rename が優先されます。
完全な例については、examples/rename_all.pyを参照してください。
tagging¶
バージョン0.7.0で新規追加。詳細は Union を参照してください。
transparent¶
transparent=True を指定すると、単一フィールドのラッパークラスはそのフィールドとして(デ)シリアライズされます(serde-rs の #[serde(transparent)] と同様)。
@serde(transparent=True)
class UserId:
value: int
assert to_json(UserId(1)) == "1"
assert from_json(UserId, "1") == UserId(1)
制約:
* init=True かつ skip=False のフィールドがちょうど1つ必要です。
* それ以外のフィールドは init=False かつ skip=True である必要があります(内部キャッシュ用途など)。
class_serializer と class_deserializer¶
バージョン0.13.0で新規追加。
クラスレベルでカスタム(デ)シリアライザを使用したい場合、class_serializer および class_deserializer 属性に(デ)シリアライザオブジェクトを渡すことができます。
カスタム(デ)シリアライザは、C++のように複数のメソッドのオーバーロードを可能にするPythonライブラリ plum に依存しています。
plumを使用すると、堅牢なカスタム(デ)シリアライザを簡単に書くことができます。
class MySerializer:
@dispatch
def serialize(self, value: datetime) -> str:
return value.strftime("%d/%m/%y")
class MyDeserializer:
@dispatch
def deserialize(self, cls: Type[datetime], value:
Any) -> datetime:
return datetime.strptime(value, "%d/%m/%y")
@serde(class_serializer=MySerializer(), class_deserializer=MyDeserializer())
class Foo:
v: datetime
旧来の serializer と deserializer との大きな違いは、 新しいclass_serializer と class_deserializer が pyserde のコード生成レベルでより深く統合されていることです。
これにより Optional や List、ネストされた dataclass を自分で処理する必要はありません。
カスタムクラスの(デ)シリアライザはすべての(デ)シリアライズのレベル(単純なデータ型から複雑なネストされたデータ構造まで、あらゆる種類の(デ)シリアライズ処理)で使用されるため、サードパーティ製の型もビルトイン型のように扱うことが可能です。
また、 * フィールドシリアライザとクラスシリアライザの両方が指定されている場合、フィールドシリアライザが優先されます。 * 旧と新のクラスシリアライザの両方が指定されている場合、新しいクラスシリアライザが優先されます。
Tip
複数の serialize メソッドを実装する場合、型チェッカーから、Redefinition of unused serializeという警告が出ることがあります。
その場合は、plum.overload と plum.dispatch を使用して回避してください。
詳細は plumのドキュメント を参照してください。
from plum import dispatch, overload
class Serializer:
# @overload を使用
@overload
def serialize(self, value: int) -> Any:
return str(value)
# @overload を使用
@overload
def serialize(self, value: float) -> Any:
return int(value)
# メソッド追加時は必ず @dispatch を追加してください。Plumが型チェッカーからの警告を消してくれます
@dispatch
def serialize(self, value: Any) -> Any:
...
完全な例については、examples/custom_class_serializer.pyを参照してください。
serializer と deserializer¶
非推奨
serializer と deserializer は、バージョン0.13.0以降、非推奨となりました。
class_serializer および class_deserializer の使用を検討してください。
クラスレベルでカスタムの(デ)シリアライザを使用したい場合、serializer および deserializer 属性に(デ)シリアライザメソッドを渡すことができます。
def serializer(cls, o):
if cls is datetime:
return o.strftime('%d/%m/%y')
else:
raise SerdeSkip()
def deserializer(cls, o):
if cls is datetime:
return datetime.strptime(o, '%d/%m/%y')
else:
raise SerdeSkip()
@serde(serializer=serializer, deserializer=deserializer)
class Foo:
a: datetime
完全な例については、examples/custom_legacy_class_serializer.py を参照してください。
type_check¶
バージョン0.9.0で新規追加。詳細は Type Check を参照してください。
serialize_class_var¶
バージョン0.9.8で新規追加。
dataclasses.fields はクラス変数を含まないため1、pyserdeはデフォルトでクラス変数をシリアライズしません。
serialize_class_var を使用することで typing.ClassVar のフィールドをシリアライズすることができます。
完全な例については、examples/class_var.pyを参照してください。
skip_if_default¶
バージョン0.30.0で新規追加。クラスデコレータに skip_if_default=True を指定すると、そのクラス内の全フィールドについて値がデフォルト(または default_factory の結果)と等しい場合に(デ)シリアライズをスキップします。フィールド側で skip_if_default を指定すればそちらが優先され、特定のフィールドだけ残す/外すことができます。
@serde(skip_if_default=True)
class Settings:
theme: str = "light"
retries: int = 3
api_key: str | None = None
note: str = field(default="keep", skip_if_default=False) # このフィールドは保持する
ネストしたdataclassや default_factory を使ったデフォルトも対象になります。動作例は examples/skip_if_default_class.py を参照してください。
skip_if_none¶
バージョン0.30.0で新規追加。クラスデコレータに skip_if_none=True を指定すると、そのクラス内のフィールドが None の場合に(デ)シリアライズをスキップします。フィールド側で skip_if_none を指定すればそちらが優先されるため、特定のフィールドだけ残す/外すこともできます。
@serde(skip_if_none=True)
class Profile:
nickname: str | None = None
bio: str | None = field(default=None, skip_if_none=False) # None でも残す
None を大量に含むペイロードをコンパクトにしたい場合に便利です。
deny_unknown_fields¶
バージョン0.22.0で新規追加。 pyserdeデコレータのdeny_unknown_fieldsオプションはデシリアライズ時のより厳格なフィールドチェックを制御できます。このオプションをTrueにするとデシリアライズ時に宣言されていないフィールドが見つかるとSerdeErrorを投げることができます。
以下の例を考えてください。
deny_unknown_fields=Trueが指定されていると、 宣言されているフィールド(この場合aとb)以外がインプットにあると例外を投げます。例えば、
完全な例については、examples/deny_unknown_fields.pyを参照してください。