当前位置: 首页 > 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.lryc.cn/news/575464.html

相关文章:

  • python pandas数据清洗
  • 【攻防篇】解决:阿里云docker 容器中自动启动xmrig挖矿
  • 解锁阿里云Datatransport:数据迁移的终极利器
  • 前端项目3-01:登录页面
  • 日语学习-日语知识点小记-进阶-JLPT-真题训练-N2阶段(4):2022年12月2023年12月
  • WPF中Converter基础用法
  • OceanBase SQL 引擎高级技术学习笔记(通俗篇)
  • 智能制造——58页智慧工厂解决方案【附全文阅读】
  • python中学物理实验模拟:斜面受力分析
  • Elasticsearch 中的精确搜索与模糊搜索
  • electron 如何配置 打开控制台
  • Android 开发 获取Debug 跟 Release 包的SHA1值
  • DeepSeek16-open-webui Pipelines开发填坑
  • C语言再出发:2025年AI时代的关键语言
  • 华为云Flexus+DeepSeek征文|基于华为云一键部署 Dify-LLM 平台,结合 MCP 工具与 DeepSeek 模型打造智能学习助手
  • 【stm32】HAL库开发——Cube配置基本定时器
  • 猴子爬山(华为OD)
  • 什么是回归测试?什么时候需要做回归测试?
  • bug复盘:MCP SSE Client 生命周期问题之context.Background() 的使用
  • B站视频下载技术揭秘:从浏览器抓包到FFmpeg音视频合成
  • 0 数学习题本
  • GraphQL注入 -- GPN CTF 2025 Real Christmas
  • 开发语言漫谈-R语言
  • Apache 支持 HTTPS
  • Hive3.1.3加载paimon-hive-connector-3.1-1.1.1.jar报错UnsatisfiedLinkError
  • C++ Programming Language —— 第3章:运算符
  • HDFS(Hadoop分布式文件系统)总结
  • 【unitrix】 4.7 库数字取反(not.rs)
  • 组织策略性陪伴顾问
  • Java后端中的并发控制:从锁机制到无锁编程的实现