タイプアダプター
你可能有不是 BaseModel
的类型,你想根据它来验证数据。或者你想验证 List[SomeModel]
,或者将其转储为 JSON。
对于此类用例,Pydantic 提供了 TypeAdapter
,它可用于类型验证、序列化和 JSON 模式生成,而无需创建 BaseModel
。
一个 TypeAdapter
实例为没有这些方法的类型(如 dataclasses、原始类型等)公开了一些来自 BaseModel
实例方法的功能:
from typing import List
from typing_extensions import TypedDict
from pydantic import TypeAdapter, ValidationError
class User(TypedDict):
name: str
id: int
user_list_adapter = TypeAdapter(List[User])
user_list = user_list_adapter.validate_python([{'name': 'Fred', 'id': '3'}])
print(repr(user_list))
#> [{'name': 'Fred', 'id': 3}]
try:
user_list_adapter.validate_python(
[{'name': 'Fred', 'id': 'wrong', 'other': 'no'}]
)
except ValidationError as e:
print(e)
"""
1 validation error for list[typed-dict]
0.id
Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='wrong', input_type=str]
"""
print(repr(user_list_adapter.dump_json(user_list)))
#> b'[{"name":"Fred","id":3}]'
!!!info " dump_json
返回 bytes
" TypeAdapter
的 dump_json
方法返回一个 bytes
对象,与对应的 BaseModel
、 model_dump_json
方法不同, model_dump_json
返回一个 str
。出现这种差异的原因是在 V1 中,模型转储返回的是 str 类型,因此在 V2 中为了向后兼容保留了这种行为。对于 BaseModel
情况, bytes
被强制转换为 str
类型,但 bytes
通常是期望的最终类型。因此,对于 V2 中的新 TypeAdapter
类,返回类型只是 bytes
,如果需要,可以很容易地将其强制转换为 str
类型。
注意
尽管在某些用例中与 RootModel
有一些重叠,但 TypeAdapter
不应被用作指定 BaseModel
等字段的类型注释。
将数据解析为指定类型¶
TypeAdapter
可用于以更特定的方式将解析逻辑应用于填充 Pydantic 模型。此函数的行为类似于 BaseModel.model_validate
,但适用于任意 Pydantic 兼容的类型。
这在你想要将结果解析为不是 BaseModel
的直接子类的类型时特别有用。例如:
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')]
TypeAdapter
能够将数据解析为 Pydantic 可以处理的任何类型,作为 BaseModel
的字段。
信息
"性能考虑因素" 创建 TypeAdapter
的实例时,必须分析提供的类型并将其转换为 pydantic-core 模式。这会带来一些相当大的开销,因此建议为给定的类型创建一个 TypeAdapter
一次,并在循环或其他性能关键的代码中重复使用它。
本文总阅读量次