Class Attributes
Class attributes can be specified as arguments in the serialize
/deserialize
decorators in order to customize the (de)serialization behaviour of the class entirely. If you want to customize a field, please consider using Field Attributes.
Attributes offered by dataclasses
frozen
dataclass frozen
class attribute works as expected.
kw_only
New in v0.12.2. dataclass kw_only
class attribute works as expected.
@serde
@dataclass(kw_only=True)
class Foo:
i: int
s: str
f: float
b: bool
See examples/kw_only.py for the complete example.
Attributes offered by pyserde
rename_all
rename_all
can converts field names into the specified string case. The following example converts camel case field names into snake case names. Case coversion depends on python-casefy. You can find the list of supported cases in the python-casefy's docs.
@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" is converted to "intField" and "str_field" is converted to "strField".
{"intField": 10, "strField": "foo"}
NOTE: If
rename_all
class attribute andrename
field attribute are used at the same time,rename
will be prioritized.@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))
The above code prints
{"intField": 10, "str-field": "foo"}
See examples/rename_all.py for the complete example.
tagging
New in v0.7.0. See Union.
class_serializer
/ class_deserializer
If you want to use a custom (de)serializer at class level, you can pass your (de)serializer object in class_serializer
and class_deserializer
class attributes. Class custom (de)serializer depends on a python library plum which allows multiple method overloading like C++. With plum, you can write robust custom (de)serializer in a quite neat way.
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
One big difference from legacy serializer
and deserializer
is the fact that new class_serializer
and class_deserializer
are more deeply integrated at the pyserde's code generator level. You no longer need to handle Optional, List and Nested dataclass by yourself. Custom class (de)serializer will be used at all level of (de)serialization so you can extend pyserde to support third party types just like builtin types.
Also,
- If both field and class serializer specified, field serializer is prioritized
- If both legacy and new class serializer specified, new class serializer is prioritized
💡 Tip: If you implements multiple
serialize
methods, you will receive "Redefinition of unusedserialize
" warning from type checker. In such case, try usingplum.overload
andplum.dispatch
to workaround it. See plum's documentation for more information.from plum import dispatch, overload class Serializer: # use @overload @overload def serialize(self, value: int) -> Any: return str(value) # use @overload @overload def serialize(self, value: float) -> Any: return int(value) # Add method time and make sure to add @dispatch. Plum will do all the magic to erase warnings from type checker. @dispatch def serialize(self, value: Any) -> Any: ...
See examples/custom_class_serializer.py for complete example.
New in v0.13.0.
serializer
/ deserializer
NOTE: Deprecated since v0.13.0. Consider using
class_serializer
andclass_deserializer
.
If you want to use a custom (de)serializer at class level, you can pass your (de)serializer methods n serializer
and deserializer
class attributes.
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
See examples/custom_legacy_class_serializer.py for complete example.
type_check
New in v0.9.0. See Type Check.
serialize_class_var
New in v0.9.8. Since dataclasses.fields
doesn't include a class variable 1, pyserde doesn't serialize class variable as default. This option allows a field of typing.ClassVar
to be serialized.
@serde(serialize_class_var=True)
class Foo:
a: ClassVar[int] = 10
See examples/class_var.py for complete example.
deny_unknown_fields
New in v0.22.0, the deny_unknown_fields
option in the pyserde decorator allows you to enforce strict field validation during deserialization. When this option is enabled, any fields in the input data that are not defined in the target class will cause deserialization to fail with a SerdeError
.
Consider the following example:
@serde(deny_unknown_fields=True)
class Foo:
a: int
b: str
With deny_unknown_fields=True
, attempting to deserialize data containing fields beyond those defined (a and b in this case) will raise an error. For instance:
from_json(Foo, '{"a": 10, "b": "foo", "c": 100.0, "d": true}')
This will raise a SerdeError
since fields c and d are not recognized members of Foo.
See examples/deny_unknown_fields.py for complete example.