在 pydantic 2 中field_validator 不再支持 each_itemtrue若需对 list[str] 中每个字符串元素执行预处理如格式转换应使用 beforevalidator 与 annotated 组合在类型注解层面定义元素级验证逻辑。在 Pydantic 1 中validator(..., each_itemTrue) 可以便捷地为 List 字段的每个元素调用验证函数。但 Pydantic 2 彻底重构了验证机制field_validator 仅作用于整个字段值即 list 对象本身不再自动遍历子项。因此将验证逻辑“下沉”到元素类型层面是实现逐项处理的标准且推荐做法。✅ 正确实现方式使用 BeforeValidator Annotated核心思路是为列表中的每个元素定义带验证的类型别名再将其用于 List[...] 注解。BeforeValidator 会在每个字符串被解析前单独调用天然支持“每项独立验证”。以下是完整、可运行的示例复制AI写代码12345678910111213141516171819202122from pydantic import BaseModel, Field, BeforeValidatorfrom typing import Annotated, Listdef complement_imports(v: str) - str:将原始模块名转换为 import 语句字符串ifnot isinstance(v, str):raise TypeError(fExpected str, got {type(v).__name__})returnfimport {v}# 定义可复用的带验证的元素类型ImportItem Annotated[str, BeforeValidator(complement_imports)]classComplementQuery(BaseModel):imports: List[ImportItem] Field(default_factorylist)subquery: str Field(...)# 测试用例print(ComplementQuery(imports[a,b], subqueryc))# 输出: imports[import a,import b] subquerycprint(ComplementQuery(subqueryc))# 输出: imports[] subqueryc⚠️ 常见误区与注意事项❌ 错误在 field_validator(imports, modebefore) 中直接处理 strmodebefore 接收的是整个 list如 [a, b]而非单个 str若函数签名写为 def complement_imports(cls, value: str) - str:将导致类型错误或逻辑失效。❌ 错误将 BeforeValidator 写在 Field(...) 内部如 Field(default_factorylist, ...)Field 的参数不接受验证器验证器必须通过 Annotated 在类型注解中声明。✅ 最佳实践提取验证函数并定义类型别名如 ImportItem不仅提升可读性与可维护性还便于在多个字段或模型中复用例如 exports: List[ImportItem]。? 补充说明BeforeValidator 执行时机早于类型转换如 str → str 本身无转换但若配合 int 等类型则会先验证后转换确保业务逻辑前置生效。总结Pydantic 2 的验证设计更强调类型即契约每个数据单元包括集合中的元素都应拥有明确、自包含的验证规则。放弃 each_item 并非功能退化而是推动开发者显式建模数据语义。对于 List[T] 的逐项处理请始终优先选择 Annotated[T, BeforeValidator(...)] 模式——它精准、安全、符合现代 Pydantic 的哲学并为未来扩展如添加 AfterValidator 或 PlainSerializer预留清晰路径。