当前位置: 首页 > news >正文

Pydantic 模型

本文将详细介绍 Pydantic 模型BaseModel 的核心概念,并通过实际代码示例如何从零开始编写自己的 Pydantic 模型。


1. Pydantic 是什么?

Pydantic 是一个 Python 库,主要用于:

  • 数据验证:确保输入数据符合预期的类型和约束。
  • 数据解析:将 JSON、字典等原始数据转换为 Python 对象。
  • 文档生成:自动生成 API 文档(如 Swagger/OpenAPI)。
  • 配置管理:安全地加载环境变量或配置文件。

2. BaseModel:所有模型的基类

Pydantic 的所有模型都继承自 BaseModel。它提供了核心功能:

  • 自动验证字段类型。
  • 支持默认值和可选字段。
  • 生成 JSON Schema(用于 API 文档)。

基础示例

from pydantic import BaseModelclass User(BaseModel):name: strage: int# 使用字典初始化
user_data = {"name": "Alice", "age": 25}
user = User(**user_data)  # 自动验证字段类型print(user.name)  # 输出: Alice
print(user.age)   # 输出: 25

3. 如何编写自己的 Pydantic 模型?

(1) 定义字段类型

Pydantic 支持 Python 原生类型和复杂类型:

from typing import Optional, List
from datetime import datetime
import uuidclass Product(BaseModel):id: uuid.UUID                  # UUID 类型name: str                      # 必填字符串price: float                   # 浮点数tags: List[str]                # 字符串列表created_at: datetime           # 日期时间discount: Optional[float] = None  # 可选字段

(2) 添加字段约束

使用 Field 定义更复杂的规则:

from pydantic import BaseModel, Fieldclass User(BaseModel):username: str = Field(..., min_length=3, max_length=20)  # 必填,长度3-20email: str = Field(..., regex=r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")age: int = Field(ge=18, description="必须成年")  # 年龄 ≥ 18

(3) 自定义验证逻辑

通过 @validator 添加自定义验证:

from pydantic import validatorclass Payment(BaseModel):amount: floatcurrency: str@validator("amount")def amount_must_be_positive(cls, v):if v <= 0:raise ValueError("金额必须大于0")return v@validator("currency")def currency_must_be_valid(cls, v):if v not in ["USD", "EUR", "JPY"]:raise ValueError("无效的货币类型")return v

(4) 嵌套模型

模型可以嵌套其他模型:

class Address(BaseModel):city: strstreet: strclass Person(BaseModel):name: straddress: Address  # 嵌套模型# 使用示例
data = {"name": "Bob","address": {"city": "New York", "street": "5th Ave"}
}
person = Person(**data)

4. 高级用法

(1) 配置模型行为

通过 Config 类自定义模型行为:

class ConfigExample(BaseModel):name: strclass Config:anystr_strip_whitespace = True  # 自动去除字符串两端空格allow_population_by_field_name = True  # 允许用别名初始化extra = "forbid"  # 禁止额外字段

(2) 生成 JSON Schema

Pydantic 自动为模型生成 JSON Schema:

print(User.schema_json(indent=2))

输出:

{"title": "User","type": "object","properties": {"username": {"type": "string","minLength": 3,"maxLength": 20},"email": {"type": "string","pattern": "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$"},"age": {"type": "integer","minimum": 18,"description": "必须成年"}},"required": ["username", "email", "age"]
}

(3) 与环境变量集成

从环境变量加载配置:

from pydantic import BaseSettingsclass Settings(BaseSettings):api_key: strdebug: bool = Falseclass Config:env_file = ".env"  # 从.env文件加载settings = Settings()  # 自动读取环境变量

5. 完整示例:用户注册 API 模型

from pydantic import BaseModel, Field, EmailStr, validator
from typing import Optional
from datetime import datetimeclass UserRegister(BaseModel):username: str = Field(..., min_length=3, max_length=20)email: EmailStr  # 专门验证邮箱格式的类型password: str = Field(..., min_length=8)birth_date: Optional[datetime] = Nonereferral_code: Optional[str] = Field(None, max_length=10)@validator("password")def password_must_contain_special_char(cls, v):if not any(c in "!@#$%^&*" for c in v):raise ValueError("密码必须包含特殊字符")return v# 使用示例
user_data = {"username": "alice123","email": "alice@example.com","password": "secure!123"
}
user = UserRegister(**user_data)  # 自动验证

6. 常见问题解答

Q1:Pydantic 和 Dataclasses 有什么区别?

  • Pydantic:专注于数据验证和解析,支持复杂约束(如正则、自定义验证)。
  • Dataclasses:仅生成 __init____repr__,无验证功能。

Q2:如何处理未知字段?

通过 Config 控制:

class Config:extra = "allow"   # 允许额外字段(默认)extra = "forbid"  # 禁止额外字段extra = "ignore"  # 忽略额外字段

Q3:性能如何?

Pydantic 在首次运行时会生成验证逻辑的优化代码,后续调用速度接近原生 Python。


总结

功能实现方式
基础字段定义name: str
字段约束Field(..., min_length=3)
自定义验证@validator 装饰器
嵌套模型直接嵌套其他 BaseModel
环境变量集成继承 BaseSettings + Config
生成 API 文档自动通过 schema_json() 或 FastAPI 集成

通过 Pydantic,你可以用极少的代码实现强大的数据验证和转换逻辑,非常适合 API 开发、配置管理和数据处理场景。

http://www.xdnf.cn/news/1069939.html

相关文章:

  • vscode运行c++文件和插件的方法
  • 信息化系统流程管理模块,企业高价值资产的跨省/市运输审批流程的功能
  • PHP基础2(流程控制,函数)
  • redis8.0新特性:t-digest计算数据百分位
  • 美团业务调整,但不裁员不降薪
  • 使用 Python 自动化文件获取:从 FTP 到 API 的全面指南
  • 力扣网C语言编程题:搜索插入位置
  • SpringBoot 中 @Transactional 的使用
  • lua 程序性能分析工具 Plua 推荐
  • CTF:PHP 多关卡绕过挑战
  • python 爬虫 下载视频
  • lua脚本为什么能保证原子性
  • 新手向:Anaconda3的安装与使用方法
  • 【UniApp 日期选择器实现与样式优化实践】
  • 大语言模型介绍
  • 推荐系统的视频特征-视频关键帧特征提取与向量生成
  • 七天学会SpringCloud分布式微服务——02——第一个微服务项目
  • Flink Oracle CDC 总结
  • 六个安全Agent设计模式:有效防止Prompt注入攻击
  • Milvus 资源调度系统的核心部分:「查询节点」「资源组」「数据库」
  • 黑马ReactDay02
  • gitlab https链接转为ssh链接
  • Android 开发 获取Debug 跟 Release 包的SHA1值
  • Host ‘db01‘ is not allowed to connect to this MariaDB server 怎么解决?
  • 原子级制造革命:双原子镧催化剂登顶Angew,焦耳超快加热技术深度解析
  • 卷积神经网络(Convolutional Neural Network, CNN)
  • 论文阅读:A Survey on Large Language Models for Code Generation
  • 量学云讲堂王岩江宇龙2025年第58期视频 主课正课系统课+收评
  • 八股文——JAVA基础:说一下C++与java的区别
  • 【笔记】Docker 配置阿里云镜像加速(公共地址即开即用,无需手动创建实例)