总结 TypedDict、Pydantic、Field、Annotated、Optional 等 Python 类型与校验工具的核心写法与组合方式
下面总结TypedDict、Pydantic、Field、Annotated、Optional这些 Python 类型与校验工具的核心写法与组合方式。1.Optional—— 可选类型作用类型提示中表示“可以是某种类型也可以是None”。等价于Union[T, None]。写法fromtypingimportOptional name:Optional[str]None# 变量可以是 str 或 None在 Pydantic 中Optional[str]本身不设置默认值需要配合 None才变为可选字段。frompydanticimportBaseModelfromtypingimportOptionalclassUser(BaseModel):nickname:Optional[str]None# 可选默认 Noneage:Optional[int]# 必填必须显式传值或 None2.TypedDict—— 结构化字典静态检查作用定义字典的键名及对应值的类型用于静态类型检查mypy、Pyright无运行时行为。基本写法fromtypingimportTypedDictclassUserDict(TypedDict):name:strage:int可选字段Python 3.11 或typing_extensionsfromtypingimportTypedDictfromtyping_extensionsimportNotRequiredclassUserDict(TypedDict):name:strage:NotRequired[int]# 键 age 可以缺失使用totalFalse全部字段可选classUserDict(TypedDict,totalFalse):name:strage:int注意TypedDict不支持Field、默认值、运行时验证。3.Pydantic—— 运行时数据验证与解析作用通过BaseModel定义模型自动完成类型转换、校验、序列化、文档生成。基本写法frompydanticimportBaseModelclassUser(BaseModel):name:strage:int可选字段默认值NoneclassUser(BaseModel):name:strage:intNone# 等价于 Optional[int] None# 或nickname:Optional[str]None运行时校验实例化时自动检查类型无效数据抛出ValidationError。4.Field—— Pydantic 字段元数据作用为 Pydantic 模型字段提供额外信息如默认值、描述、验证约束、别名等。基本写法frompydanticimportBaseModel,FieldclassProduct(BaseModel):name:strField(...,min_length1,description产品名称)price:floatField(gt0,le10000,description价格)stock:intField(default0,ge0)常用参数default默认值default_factory生成默认值的可调用对象gt,ge,lt,le数值范围min_length,max_length字符串长度regex正则表达式description描述用于生成 JSON Schemaalias字段别名5.Annotated—— 类型元数据容器作用Python 3.9 引入将额外信息如验证、描述附着到类型上供工具或库解析。基本写法fromtypingimportAnnotated# 附加一个字符串元数据UserNameAnnotated[str,用户的姓名]与 Pydantic 结合最常用frompydanticimportBaseModel,Field,PositiveIntfromtypingimportAnnotatedclassUser(BaseModel):age:Annotated[int,Field(gt0,lt150,description年龄)]score:Annotated[float,Field(ge0,le100)]uid:Annotated[int,PositiveInt()]# 使用 annotated-types 库的约束与TypedDict结合Pydantic 支持fromtypingimportTypedDict,AnnotatedfrompydanticimportField,TypeAdapterclassUserDict(TypedDict):name:Annotated[str,Field(min_length1)]age:Annotated[int,Field(gt0)]# 运行时验证adapterTypeAdapter(UserDict)dataadapter.validate_python({name:张三,age:25})6. 组合对比TypedDictvsPydantic BaseModel特性TypedDictPydantic BaseModel目的静态类型检查运行时验证 序列化默认值❌✅Field(default...)可选字段NotRequired或totalFalseOptional[T] None字段描述❌✅Field(description...)数值约束❌✅Field(gt0)运行时类型转换❌✅如123→123JSON Schema 生成❌需第三方✅.model_json_schema()内存/性能极低纯字典较高模型实例7. 最佳实践组合建议仅需静态类型检查无运行时逻辑TypedDictNotRequiredOptional需要运行时校验 默认值 API 文档Pydantic BaseModelFieldOptional需要强约束但想用字典结构例如已存在字典数据TypedDictAnnotated Pydantic 的TypeAdapter复杂校验逻辑跨字段验证Pydantic 模型的model_validator或field_validator示例一个企业级数据模型PydanticfrompydanticimportBaseModel,Field,field_validatorfromtypingimportOptional,AnnotatedclassStudent(BaseModel):name:Annotated[str,Field(min_length2,max_length20)]age:Annotated[int,Field(ge6,le30)]gender:Optional[str]Field(None,pattern^(男|女|其他)$)grades:list[int]Field(default_factorylist,max_items50)field_validator(grades)defcheck_grades(cls,v):ifany(g0org100forginv):raiseValueError(成绩必须在 0~100 之间)returnv8. 关键易错点Optional[T]不等于T | None语义相同但Optional[T] None才使字段可选若只写Optional[T]仍是必填。TypedDict的字段名在运行时是普通字典键不会被转换为属性。Annotated中的元数据顺序可任意但通常第一个是类型后面跟多个元数据项。Pydantic 的Field(default...)与Annotated结合时避免在Annotated内外重复定义默认值会导致歧义。