当前位置: 首页 > 知识库问答 >
问题:

python - pydantic v2 下,如何实现对象化一个列表?

钱劲
2024-05-20

pydantic v2 下,如何实现对象化一个列表?作为 ptdantic v1 下 parse_obj_as 的替代品

需求:

一般都是把 dict 转成 pydantic 对象,但是如果我有很多个 dict,我需要转成一堆 pydantic 对象,比如把 list[dict] 转成 list[Item], 我会用列表生成式 [Item.model_validate(d) for d in dict_list]

但是有除了列表生成式之外更加优雅的方式吗?而且我主要担心的是,列表生成式不是最佳性能方案?

因为有一个程序需要频繁且巨量的序列化和反序列化,我需要关注性能


下面是 chatgpt 给我的答案:

如果你希望避免创建额外的 Pydantic 模型,同时直接对象化一个列表,可以利用 Pydantic 的 parse_obj_as 函数。这个函数允许你将一个普通的列表解析为 Pydantic 对象的列表。

下面是一个简洁的例子,展示如何直接对象化一个列表,而不需要创建额外的容器模型:

  1. 定义 Pydantic 模型

    • 仅定义一个表示列表项的模型。
from pydantic import BaseModel, parse_obj_asfrom typing import Listclass Item(BaseModel):    id: int    name: str# 示例数据data = [    {"id": 1, "name": "Item 1"},    {"id": 2, "name": "Item 2"}]# 解析数据items = parse_obj_as(List[Item], data)# 打印结果for item in items:    print(item)

在这个例子中:

  • Item 模型表示列表中的单个项。
  • data 是一个字典列表,表示需要解析的数据。
  • parse_obj_as(List[Item], data)data 解析为 Item 对象的列表。
  1. 访问列表中的数据

    • 解析后的 itemsItem 对象的列表,可以直接操作。
for item in items:    print(f"ID: {item.id}, Name: {item.name}")

这种方法避免了创建额外的容器模型,保持了代码的简洁性,同时利用 Pydantic 的数据验证和类型检查功能。

上面的回答在 pydantic v1 下面确实是可以使用的,但是 pydantic v2 的 api 变更了

图片.png

@deprecated(    '`parse_obj_as` is deprecated. Use `pydantic.TypeAdapter.validate_python` instead.',    category=None,)def parse_obj_as(type_: type[T], obj: Any, type_name: NameFactory | None = None) -> T:    warnings.warn(        '`parse_obj_as` is deprecated. Use `pydantic.TypeAdapter.validate_python` instead.',        category=PydanticDeprecatedSince20,        stacklevel=2,    )    if type_name is not None:  # pragma: no cover        warnings.warn(            'The type_name parameter is deprecated. parse_obj_as no longer creates temporary models',            DeprecationWarning,            stacklevel=2,        )    return TypeAdapter(type_).validate_python(obj)

因为 chatgpt 的数据库比较老,只有 pydantic v1 的,而我需要 v2 的

但是关于上面的代码提示我不知道去哪里导入 validate_python?

图片.png

共有1个答案

秦博延
2024-05-20

TypeAdapter:https://docs.pydantic.dev/2.1/usage/type_adapter/

from typing import Listfrom pydantic import BaseModel, TypeAdapterclass Item(BaseModel):    id: int    name: str# `item_data` could come from an API call, eg., via something like:# item_data = requests.get('https://my-api.com/items').json()item_data = [{'id': 1, 'name': 'My Item'}]items = TypeAdapter(List[Item]).validate_python(item_data)print(items)#> [Item(id=1, name='My Item')]
 类似资料:
  • 如果一封邮件被发送到我的收件箱,我会收到一条消息,并将内容插入数据库。我有一个组织。springframework。整合。果心信息如下: 现在,如果出现故障,我希望有故障安全恢复机制,我想的是将消息对象序列化到一个文件中,然后反序列化并更新到DB。 问题1。在这种情况下,如何序列化消息对象?2。除了序列化,还可以使用其他机制吗? 编辑我以前没有做过序列化,我听说类应该实现Serializable,

  • 本文向大家介绍Python面向对象实现一个对象调用另一个对象操作示例,包括了Python面向对象实现一个对象调用另一个对象操作示例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python面向对象实现一个对象调用另一个对象操作。分享给大家供大家参考,具体如下: 我先总结一下python中的类的特点: 1.类中所有的方法的参数中都必须加self,并且是第一个参数 2.__init__方法用

  • null 但是,当我以Yar-Client模式提交Spark应用程序时,抛出了以下异常: 线程“main”org.apache.spark.sparkException:Task not serializable at org.apache.spark.util.closureCleaner$.ensureRecleaner.ccala:166)at org.apache.spark.util.c

  • 问题内容: 我问了一个先前的问题,关于如何将多个保存文件保存到.ser文件中,建议我使用哈希集,因为它们是可序列化的。我试图编写一段测试代码来序列化哈希集内的每条信息: 但是我在获取代码来编写带有index(i)的对象时遇到了麻烦,因为它说未为type定义该方法。有没有一种方法可以遍历哈希集中的每条信息,还是应该一次序列化整个集合。另一个问题是,如果第一个答案是后者,我将如何将数据反序列化为单独的

  • 我怎么才能修好这个?我需要用JSON编写响应。一个解决方案是非常赞赏的。

  • 问题 你需要将一个Python对象序列化为一个字节流,以便将它保存到一个文件、存储到数据库或者通过网络传输它。 解决方案 对于序列化最普遍的做法就是使用 pickle 模块。为了将一个对象保存到一个文件中,可以这样做: import pickle data = ... # Some Python object f = open('somefile', 'wb') pickle.dump(data