将数据类转换为marshmallow模式的Python库。
项目描述
marshmallow-dataclass
从数据类自动生成marshmallow模式。
from dataclasses import dataclass, field
from typing import List, Optional
import marshmallow_dataclass
import marshmallow.validate
@dataclass
class Building:
# field metadata is used to instantiate the marshmallow field
height: float = field(metadata={"validate": marshmallow.validate.Range(min=0)})
name: str = field(default="anonymous")
@dataclass
class City:
name: Optional[str]
buildings: List[Building] = field(default_factory=list)
city_schema = marshmallow_dataclass.class_schema(City)()
city = city_schema.load(
{"name": "Paris", "buildings": [{"name": "Eiffel Tower", "height": 324}]}
)
# => City(name='Paris', buildings=[Building(height=324.0, name='Eiffel Tower')])
city_dict = city_schema.dump(city)
# => {'name': 'Paris', 'buildings': [{'name': 'Eiffel Tower', 'height': 324.0}]}
为什么
在Python中使用模式通常意味着既有表示数据的类,又有表示其模式的类,这会导致重复的代码可能不一致。自Python 3.6起,可以为类成员定义类型,这允许库自动生成模式。
因此,您可以以允许您静态检查代码是否与文档匹配的方式记录API。
安装
此软件包托管在PyPI上。
pip3 install marshmallow-dataclass
pip3 install "marshmallow-dataclass"
marshmallow 2支持
marshmallow-dataclass
不再支持marshmallow 2。如果您需要marshmallow 2兼容性,请安装marshmallow_dataclass<6.0
。
使用
使用class_schema
函数从dataclass
生成一个marshmallow Schema类。
from dataclasses import dataclass
from datetime import date
import marshmallow_dataclass
@dataclass
class Person:
name: str
birth: date
PersonSchema = marshmallow_dataclass.class_schema(Person)
您的字段类型必须是 marshmallow 支持的基本类型之一(例如 float
、str
、bytes
、datetime
等),Union
或其他数据类。
Union(反)序列化强制转换
通常是指 Union 类型;Union[X, Y]
从集合论的角度来看意味着 X
或 Y
,即一个无序集,然而子类型的顺序定义了在尝试反序列化或序列化值时的优先级,具体请参见此处。
例如,
from typing import Union
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: Union[int, float]
PersonSchema = marshmallow_dataclass.class_schema(Person)
PersonSchema().load({"name": "jane", "age": 50.0})
# => Person(name="jane", age=50)
会首先尝试将 50.0
强制转换为 int
。如果不想进行强制转换,可以使用 Any
类型,但要注意,如果没有额外的验证,则不会进行类型检查。
自定义生成的字段
要向生成的 marshmallow 字段传递参数(例如,validate
、load_only
、dump_only
等),请将它们传递给 field
函数的 metadata
参数。
注意,从版本 4 开始,marshmallow 将禁止传递任意参数,因此任何附加的元数据都应该放在它自己的 metadata
字典中。
from dataclasses import dataclass, field
import marshmallow_dataclass
import marshmallow.validate
@dataclass
class Person:
name: str = field(
metadata=dict(
load_only=True, metadata=dict(description="The person's first name")
)
)
height: float = field(metadata=dict(validate=marshmallow.validate.Range(min=0)))
PersonSchema = marshmallow_dataclass.class_schema(Person)
@dataclass
快捷方式
marshmallow_dataclass
提供了一个与标准库中的 @dataclasses.dataclass
相似行为的 @dataclass
装饰器,并添加了一个带有生成的 marshmallow Schema 属性。
# Use marshmallow_dataclass's @dataclass shortcut
from marshmallow_dataclass import dataclass
@dataclass
class Point:
x: float
y: float
Point.Schema().dump(Point(4, 2))
# => {'x': 4, 'y': 2}
注意:由于 .Schema
属性是动态添加的,可能会混淆类型检查器。为了避免这种情况,可以将 Schema
声明为 ClassVar
。
from typing import ClassVar, Type
from marshmallow_dataclass import dataclass
from marshmallow import Schema
@dataclass
class Point:
x: float
y: float
Schema: ClassVar[Type[Schema]] = Schema
自定义基础 Schema
您还可以从自己的基础 Schema 类派生所有 Schema(请参阅marshmallow 关于扩展 Schema
的文档)。这允许您实现自定义(反)序列化行为,例如指定类与 marshmallow 字段之间的自定义映射,或在序列化时重命名字段。
类与字段之间的自定义映射
class BaseSchema(marshmallow.Schema):
TYPE_MAPPING = {CustomType: CustomField, List: CustomListField}
class Sample:
my_custom: CustomType
my_custom_list: List[int]
SampleSchema = marshmallow_dataclass.class_schema(Sample, base_schema=BaseSchema)
# SampleSchema now serializes my_custom using the CustomField marshmallow field
# and serializes my_custom_list using the CustomListField marshmallow field
在序列化时重命名字段
import marshmallow
import marshmallow_dataclass
class UppercaseSchema(marshmallow.Schema):
"""A Schema that marshals data with uppercased keys."""
def on_bind_field(self, field_name, field_obj):
field_obj.data_key = (field_obj.data_key or field_name).upper()
class Sample:
my_text: str
my_int: int
SampleSchema = marshmallow_dataclass.class_schema(Sample, base_schema=UppercaseSchema)
SampleSchema().dump(Sample(my_text="warm words", my_int=1))
# -> {"MY_TEXT": "warm words", "MY_INT": 1}
您还可以将 base_schema
传递给 marshmallow_dataclass.dataclass
。
@marshmallow_dataclass.dataclass(base_schema=UppercaseSchema)
class Sample:
my_text: str
my_int: int
请参阅 marshmallow 关于扩展 Schema
的文档。
自定义类型别名
此库允许您使用 Python 的 Annotated 类型 PEP-593 来指定自定义 marshmallow 字段。
from typing import Annotated
import marshmallow.fields as mf
import marshmallow.validate as mv
IPv4 = Annotated[str, mf.String(validate=mv.Regexp(r"^([0-9]{1,3}\\.){3}[0-9]{1,3}$"))]
您还可以传递一个 marshmallow 字段类。
from typing import Annotated
import marshmallow
from marshmallow_dataclass import NewType
Email = Annotated[str, marshmallow.fields.Email]
为了方便起见,提供了一些自定义类型
from marshmallow_dataclass.typing import Email, Url
当使用 Python 3.8 时,必须从 typing_extensions 包导入 Annotated
# Version agnostic import code:
if sys.version_info >= (3, 9):
from typing import Annotated
else:
from typing_extensions import Annotated
自定义 NewType 声明 [已弃用]
NewType 已弃用,改用上面描述的类型别名。
此库导出 NewType
函数以创建生成 自定义 marshmallow 字段 的类型。
NewType
的关键字参数传递给 marshmallow 字段构造函数。
import marshmallow.validate
from marshmallow_dataclass import NewType
IPv4 = NewType(
"IPv4", str, validate=marshmallow.validate.Regexp(r"^([0-9]{1,3}\\.){3}[0-9]{1,3}$")
)
您还可以将 marshmallow 字段传递给 NewType
。
import marshmallow
from marshmallow_dataclass import NewType
Email = NewType("Email", str, field=marshmallow.fields.Email)
注意:如果您使用 mypy
,您会注意到如果使用 NewType
定义的变量在类型注解中使用,mypy
会抛出一个错误。为了解决这个问题,将 marshmallow_dataclass.mypy
插件添加到您的 mypy
配置中,例如。
[mypy]
plugins = marshmallow_dataclass.mypy
# ...
Meta
选项
Meta
选项 的设置方式与 marshmallow 的 Schema
相同。
from marshmallow_dataclass import dataclass
@dataclass
class Point:
x: float
y: float
class Meta:
ordered = True
文档
项目文档托管在GitHub Pages上:https://lovasoa.github.io/marshmallow_dataclass/
贡献
要安装此项目并在本地对其进行更改,请遵循CONTRIBUTING.md
中的说明。
项目详情
下载文件
下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源代码分发
构建分发
marshmallow_dataclass-8.7.1.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 4fb80e1bf7b31ce1b192aa87ffadee2cedb3f6f37bb0042f8500b07e6fad59c4 |
|
MD5 | f158473050f0e91ccb87be8090e7f439 |
|
BLAKE2b-256 | 0123a863a5d569f03454d733f884a72415ac3f1e1b1b3215de3a9f4f621a83a6 |