pydantic v2 下,如何实现对象化一个列表?
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 对象的列表。下面是一个简洁的例子,展示如何直接对象化一个列表,而不需要创建额外的容器模型:
定义 Pydantic 模型:
- 仅定义一个表示列表项的模型。
from pydantic import BaseModel, parse_obj_as from typing import List class 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
对象的列表。
访问列表中的数据:
- 解析后的
items
是Item
对象的列表,可以直接操作。for item in items: print(f"ID: {item.id}, Name: {item.name}")
这种方法避免了创建额外的容器模型,保持了代码的简洁性,同时利用 Pydantic 的数据验证和类型检查功能。
上面的回答在 pydantic v1 下面确实是可以使用的,但是 pydantic v2 的 api 变更了
@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?
回复
1个回答

test
2024-06-19
TypeAdapter:https://docs.pydantic.dev/2.1/usage/type_adapter/
from typing import List
from pydantic import BaseModel, TypeAdapter
class 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')]
回复

适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容