pydantic 🚀

您所在的位置:网站首页 coerce用法 pydantic 🚀

pydantic 🚀

2023-05-06 13:42| 来源: 网络整理| 查看: 265

我认为,通过在我的原始帖子中使用float作为示例,我可能会搅浑水,并且建议更改__init__和parse_obj的工作方式会增加混乱,所以我为此道歉。 我想我们在这里谈论的有点过头了,让我们退后一步,我会重申我的用例。

我的目标是使用 Pydantic 在我的后端系统中定义域类型,这些域类型可以利用 Pydantic 的 JSON Schema 功能通过网络边界桥接到其他语言(例如 Javascript)的系统。 我的想法是,我将能够定义一个具有 UUID、头发颜色和许多衬衫的用户:

class HairColor(Enum): RED = auto() BROWN = auto() BLONDE = auto() BLUE = auto() class User(BaseModel): uuid: UUID4 hair_color: HairColor num_shirts: int = Field(..., le=100)

感谢 Pydantic 的 JSON Schema 功能,我现在可以使用 OpenAPI 的 codegen 库为 Javascript 自动生成客户端库。 这样一来,我的前端就永远不可能通过网络发送无效的头发颜色或num_shirts的非法大值。 这些约束可能对我的系统至关重要,通过确保所有域类型在构造上都是正确的,并通过使用 Typescript 和 Mypy 等类型检查器,我可以在这些网络中扩展这些约束的类型安全性边界并证明关于我的系统的重要属性。

基本上,我可以将我的对象的形状作为实现细节并假装网络边界不存在以用于我的应用程序逻辑,这极大地简化了开发,同时提高了正确性。

然而,想象一下我的前端应用程序中出现了一个奇怪的错误,它以某种方式绕过了我的自动生成的客户端并将一些其他值放入num_shirts中,恰好是1.2 ,但实际上完全代表了其他类型。 如前所述,上面的模型会默默地忽略该错误,将1.2 : float强制转换为1 : int 。 由于它意外地通过了 maxImum 约束,因此这个错误可能会无限期地持续存在,我最终可能会遇到令人讨厌的数据损坏问题。 我可以使用StrictInt ,但是我必须记住(并让我的整个团队记住)始终使用StrictInt而不是更自然的int 。

无论我使用int还是StrictInt ,我都可以按照 Pydantic 文档中的建议反序列化User :

>>> data == '{"uuid": "f84ede9d-fb19-4f35-8223-a209a858df57", "hair_color": 1, "num_shirts": 5}' >>> User(**json.loads(data)) User(uuid=UUID4(f84ede9d-fb19-4f35-8223-a209a858df57), hair_color=HairColor.BROWN, num_shirts=5)

所以本质上,我正在寻找一个(反)序列化器,它能够轻松地将有线格式解析为类型安全的域类型,包括非原始类型(例如上面示例中的 UUID),并且可以在没有信息的情况下解析损失。 我不需要运行时类型检查器,如果需要,我可以编写一个,或者我可以使用 PyPI 上提供该功能的其他项目之一。 Pydantic 几乎是我正在寻找的,除了在解析某些类型(例如 bool、float、datetime)时它是宽松的,这样可能会发生信息丢失,这可能会隐藏错误(这会很糟糕)。

使非严格类型表现得像严格类型一样的类级别标志(或不同的基类)将满足我的用例:我仍然能够轻松地从原始数据中解析复杂类型,并且信息丢失的风险将被移除。 用isinstance检查替换非严格解析器的标志将消除我解析复杂类型的能力:

data = {"uuid": "f84ede9d-fb19-4f35-8223-a209a858df57", "hair_color": 1, "num_shirts": 5} >>> User(data) Error: uuid is not of type UUID4, hair_color is not of type HairColor >>> # I'd have to take extra steps to parse this type: >>> User(uuid=UUID4(data['uuid'], hair_color=[k for k in HairColor if k.value == data['hair_color']][0], num_shirts=5) User(uuid=UUID4(f84ede9d-fb19-4f35-8223-a209a858df57), hair_color=HairColor.BROWN, num_shirts=5)

总之,我还是希望 Pydantic 是一个解析库,我只是希望能够把它配置得更挑剔。

显然,这不会满足我让所有解析立即符合forall x: x == serialize(deserialize(x))的愿望:所有日期时间类型都有更宽松的解析器,我怀疑还有其他边缘情况。 但是这些类型的严格版本可能会随着时间的推移而添加,并且它们的添加与使用类级别标志在宽松和严格版本之间切换的能力是正交的。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3