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_fieldintField に、str_fieldstrField に変換されます。

{"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_serializerclass_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

旧来の serializerdeserializer との大きな違いは、 新しいclass_serializerclass_deserializer が pyserde のコード生成レベルでより深く統合されていることです。
これにより Optional や List、ネストされた dataclass を自分で処理する必要はありません。

カスタムクラスの(デ)シリアライザはすべての(デ)シリアライズのレベル(単純なデータ型から複雑なネストされたデータ構造まで、あらゆる種類の(デ)シリアライズ処理)で使用されるため、サードパーティ製の型もビルトイン型のように扱うことが可能です。

また、

  • フィールドシリアライザとクラスシリアライザの両方が指定されている場合、フィールドシリアライザが優先されます。
  • 旧と新のクラスシリアライザの両方が指定されている場合、新しいクラスシリアライザが優先されます。

💡 ヒント:複数の serialize メソッドを実装する場合、型チェッカーから、Redefinition of unused serializeという警告が出ることがあります。
その場合は、plum.overloadplum.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を参照してください。

serializerdeserializer

注記: 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を参照してください。