Class Attributes
クラス属性は、クラスの(デ)シリアライズの動作をカスタマイズするために serialize
/ deserialize
デコレータの引数として指定できます。
フィールドをカスタマイズしたい場合は、フィールド属性の使用を検討してください。
dataclassesの属性
frozen
dataclassの frozen
クラス属性は期待通りに機能します。
kw_only
バージョン0.12.2で新規追加。dataclassの kw_only
クラス属性は期待通りに機能します。
@serde
@dataclass(kw_only=True)
class Foo:
i: int
s: str
f: float
b: bool
完全な例については、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
に変換されます。
{"intField": 10, "strField": "foo"}
注記:
rename_all
クラス属性とrename
フィールド属性が同時に使用される場合、rename
が優先されます。@serde(rename_all = 'camelcase') class Foo: int_field: int str_field: str = field(rename='str-field') f = Foo(int_field=10, str_field='foo') print(to_json(f))
上記のコードは以下を出力します。
{"intField": 10, "str-field": "foo"}
完全な例については、examples/rename_all.pyを参照してください。
tagging
バージョン0.7.0で新規追加。詳細は Union を参照してください。
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 を自分で処理する必要はありません。
カスタムクラスの(デ)シリアライザはすべての(デ)シリアライズのレベル(単純なデータ型から複雑なネストされたデータ構造まで、あらゆる種類の(デ)シリアライズ処理)で使用されるため、サードパーティ製の型もビルトイン型のように扱うことが可能です。
また、
- フィールドシリアライザとクラスシリアライザの両方が指定されている場合、フィールドシリアライザが優先されます。
- 旧と新のクラスシリアライザの両方が指定されている場合、新しいクラスシリアライザが優先されます。
💡 ヒント:複数の
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
のフィールドをシリアライズすることができます。
@serde(serialize_class_var=True)
class Foo:
a: ClassVar[int] = 10
完全な例については、examples/class_var.pyを参照してください。
deny_unknown_fields
バージョン0.22.0で新規追加。 pyserdeデコレータのdeny_unknown_fields
オプションはデシリアライズ時のより厳格なフィールドチェックを制御できます。このオプションをTrueにするとデシリアライズ時に宣言されていないフィールドが見つかるとSerdeError
を投げることができます。
以下の例を考えてください。
@serde(deny_unknown_fields=True)
class Foo:
a: int
b: str
deny_unknown_fields=True
が指定されていると、 宣言されているフィールド(この場合aとb)以外がインプットにあると例外を投げます。例えば、
from_json(Foo, '{"a": 10, "b": "foo", "c": 100.0, "d": true}')
上記のコードはフィールドcとdという宣言されていないフィールドがあるためエラーとなります。
完全な例については、examples/deny_unknown_fields.pyを参照してください。