Pydantic v2中如何将TypedDict的bs字段设为可选字段?
解决Pydantic校验TypedDict时可选字段报错的问题
问题根源在于TypedDict的默认规则:默认所有字段都是必填项,你原来写的bs: Optional[List[B]] = None只是给字段设置了默认值,但并没有把字段本身标记为可选,所以Pydantic校验时会强制要求bs字段必须存在。
要让bs字段本身可选(即允许数据中完全没有该字段),有两种实用方法:
方法一:使用NotRequired(Python 3.10+推荐)
用typing.NotRequired标记bs字段为可选,既允许字段不存在,也保留了Optional让字段值可以为None:
from typing import Optional, TypedDict, List, NotRequired from pydantic import TypeAdapter class B(TypedDict): number: int class A(TypedDict): name: str value: int bs: NotRequired[Optional[List[B]]] # 标记字段本身可选,值可为列表或None data_with_list = { "name":"alfa", "value":1, "bs" : [{"number":1001}, {"number":1002}] } data_with_empty_list = { "name":"beta", "value":2, "bs" : [{"number":1003}, {"number":1004}] } data_with_no_list = { "name":"gamma", "value":3, } ta = TypeAdapter(A) ta.validate_python(data_with_list) # 正常通过 ta.validate_python(data_with_empty_list) # 正常通过 ta.validate_python(data_with_no_list) # 不再触发"Field required"错误
如果不需要bs的值为None,只允许字段不存在或者是有效列表,可以简化为bs: NotRequired[List[B]]。
方法二:用total=False配合Required(兼容Python 3.9及以下)
若你的Python版本低于3.10,没有NotRequired,可以给TypedDict设置total=False(默认所有字段可选),再用Required标记必须存在的字段:
from typing import Optional, TypedDict, List, Required from pydantic import TypeAdapter class B(TypedDict): number: int class A(TypedDict, total=False): name: Required[str] # 标记为必填字段 value: Required[int] # 标记为必填字段 bs: Optional[List[B]] # 未标记Required,因此为可选字段 # 后续数据和校验代码同上,三个数据均可正常通过校验
内容的提问来源于stack exchange,提问作者Peder
相关产品推荐
相关产品推荐

