游乐游手机版
首页/编程语言/文章详情

Pydantic BaseModel 入门教程

时间:2026-07-18 20:58
PydanticBaseModel通过自定义元类在类定义阶段编译注解为CoreSchema,由Rust引擎执行高速验证与序列化。支持字段元信息、部分更新、额外字段收纳、严格模式、嵌套与递归模型、字段约束及自定义校验等特性。

Pydantic BaseModel 核心源码解析

 复制代码class BaseModel(metaclass=_model_construction.ModelMetaclass):
    """!!! abstract "Usage Documentation"
        [Models](../concepts/models.md)    A base class for creating Pydantic models.    Attributes:
        __class_vars__: The names of the class variables defined on the model.
        __private_attributes__: Metadata about the private attributes of the model.
        __signature__: The synthesized `__init__` [`Signature`][inspect.Signature] of the model.        __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
        __pydantic_core_schema__: The core schema of the model.
        __pydantic_custom_init__: Whether the model has a custom `__init__` function.
        __pydantic_decorators__: Metadata containing the decorators defined on the model.
            This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.
        __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
            The `origin` and `args` items map to the [`__origin__`][genericalias.__origin__]
            and [`__args__`][genericalias.__args__] attributes of [generic aliases][types-genericalias],
            and the `parameter` item maps to the `__parameter__` attribute of generic classes.
        __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
        __pydantic_post_init__: The name of the post-init method for the model, if defined.
        __pydantic_root_model__: Whether the model is a [`RootModel`][pydantic.root_model.RootModel].
        __pydantic_serializer__: The `pydantic-core` `SchemaSerializer` used to dump instances of the model.
        __pydantic_validator__: The `pydantic-core` `SchemaValidator` used to validate instances of the model.        __pydantic_fields__: A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects.
        __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] objects.        __pydantic_extra__: A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra]
            is set to `'allow'`.
        __pydantic_fields_set__: The names of fields explicitly set during instantiation.
        __pydantic_private__: Values of private attributes set on the model instance.
    """	__pydantic_fields__: ClassVar[Dict[str, FieldInfo]]  # noqa: UP006
    """A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects.
    This replaces `Model.__fields__` from Pydantic V1.
    """	__pydantic_extra__: Dict[str, Any] | None = _model_construction.NoInitField(init=False)  # noqa: UP006
    """A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra] is set to `'allow'`."""

元类机制:性能提升的基石

与普通 Python 类不同,BaseModel 采用了自定义元类 ModelMetaclass。当子类被定义时,元类会在解释器读取类体时,自动收集所有类型注解(__annotations__),并生成对应的核心数据结构(CoreSchema)。这也是 Pydantic 性能卓越的第一重秘密:将大量工作前置到类定义阶段,实例化时仅需调用已编译好的 Rust 验证器,大幅提升效率。

Pydantic学习--BaseModel

核心验证架构:V2 性能飞跃的关键

 复制代码__pydantic_core_schema__: ClassVar[CoreSchema]
__pydantic_serializer__: ClassVar[SchemaSerializer] # SchemaValidator:负责实例化时的数据校验与强制转换。
__pydantic_validator__: ClassVar[SchemaValidator | PluggableSchemaValidator] # chemaSerializer:负责高速地序列化为 Python 字典或 JSON。

这是 Pydantic V2 与 V1 之间最大的架构差异。在 V1 中,验证逻辑完全由 Python 编写,性能相对较慢。而在 V2 中,元类首先将模型声明编译成 CoreSchema,随后交由 Rust 编写的 pydantic-core 库处理,实现了显著的速度提升。

字段与状态管理:数据完整性的保障

  • __pydantic_fields__:存储了模型中所有字段的元信息(默认值、是否必填、别名等),由元类在定义阶段自动填充。
  • __pydantic_fields_set__至关重要。它记录了实例化时你显式传递了哪些字段。这能精确区分“未传值”与“主动传了 None”,在处理 PATCH 操作或部分更新时极其有用。
  • __pydantic_extra__:当模型配置了 extra='allow',所有未定义的额外字段会被安全收纳到这里,确保数据不丢失。

实战案例:从基础到进阶

基础操作示例

  1. 基础操作:访问模型数据
 复制代码from typing import *
from pydantic import BaseModel, ValidationError, ConfigDict, Fieldclass User(BaseModel):
    age: int
    name: try:
    user2 = User(age="10000", name="ak") # 不会报错,原因:Pydantic默认为宽松模式,内置类型强制转换,尽量转数据类型
    print(f"{type(user2.age)}")
except ValidationError as e:
    print(f"发生报错:{e}")
  1. 防止字段隐式转换:配置严格模式
 复制代码from pydantic import BaseModel, ValidationError, ConfigDict, Fieldclass User(BaseModel):
    model_config = ConfigDict(strict=True) # 所有字段开启严格校验    age: int
    name: strclass User(BaseModel):
    age: int = Field(strict=True) # 指明这个字段拒绝隐式转换
    name: str
  1. 序列化与反序列化:数据转换与恢复
 复制代码# 序列化
dict_1 = user1.model_dump()
json_1 = user1.model_dump_json()print(f"dict_1={dict_1} n json_1={json_1}")
#dict_1={'age': 20, 'name': 'AK'}
# json_1={"age":20,"name":"AK"}# 反序列化
new_User = User.model_validate_json(json_1)
print(new_User) # 打印输出:age=20 name='AK'
  1. 增加字段、查看原有字段:灵活扩展模型
 复制代码class User(BaseModel):
    model_config = ConfigDict(extra="allow") # 允许增加字段    age: int
    name: struser1 = User(name="AK", age=20, color="blue")
print(f"显示传递:{user1.__pydantic_fields_set__} t 未定义字段:{user1.__pydantic_extra__}") 
# 打印输出:显示传递:{'color', 'age', 'name'}         未定义字段:{'color': 'blue'}

进阶应用技巧

  1. 增加字段复杂度,如嵌套数据结构
 复制代码class Item(BaseModel):
    name: str
    price: floatclass Order(BaseModel):
    order_id: str
    items: List[Item]       # 包含多个Item对象的列表
    status: Tuple[str, str] # 元组:(订单状态, 配送状态)order_data = {
    'order_id': "741239478921",
    'items': [
        {'name': "Laptop", 'price': 100.1},
        {'name': "Mouse", 'price': 49.9}
    ],
    'status': ("Paid", "Shipped")
}order = Order(**order_data) # 通过字典,然后解包**,实例化对象
print(f"order= {order}")
  1. 模型继承,共享相同字段:复用基础结构
 复制代码class Base1(BaseModel):
    a: str
    b: str
    c: strclass Test_Base1(Base1):
    price: intte = Test_Base1(a="", b="", c="", price=10)
print(te) # a='' b='' c='' price=10
  1. 树形递归结构:处理层级数据模型
 复制代码class Department(BaseModel):
    id: int
    name: str
    children: Optional[List['Department']] = None # 递归类型注解:子节点依然是 Department 对象的列表# 传入嵌套字典,自动解析为树形对象
dept_data = {
    "id": 1, "name": "总公司", 
    "children": [
        {"id": 2, "name": "研发部", "children": None},
        {"id": 3, "name": "市场部", "children": [
            {"id": 4, "name": "华南区", "children": None}
        ]}
    ]
}dept = Department(**dept_data)
print(dept)
# id=1 name='总公司' children=[Department(id=2, name='研发部', children=None), Department(id=3, name='市场部', children=[Department(id=4, name='华南区', children=None)])]
  1. 字段约束:精细化数据规则
 复制代码from typing import Annotatedclass Product(BaseModel):
    name: str = Field(min_length=2, max_length=10)
    
    price: Annotated[float, Field(..., ge=0, description="产品价格")] 
    price2: float = Field(..., ge=0, description="产品价格")
  1. 自定义业务逻辑校验
 复制代码from pydantic import field_validator, model_validator
class Item(BaseModel):
    name: str
    price: floatclass OrderInfo(BaseModel):
    user_email:str
    items: List[Item]
    total_amount: float    # 验证字段user_email,确保邮箱含有字符@
    @field_validator('user_email')
    @classmethod
    def validate_email(cls, value:str) -> str:
        if '@' not in value:
            raise ValidationError("Email must contain "@" symbol")
        return value
    
    # 跨字段校验
    @model_validator(mode='after')
    def check_total_amout(self) -> 'OrderInfo':
        # 自定义策略
        if self.items and self.total_amount is not None:
            total_price = sum( item.price for item in self.items)
            if total_price > self.total_amount:
                raise ValueError('Total amount cannot be less than the sum of item prices.')
        return self

validate_email() 函数的逻辑并不复杂:实例化 OrderInfo 时,@field_validator 会专门对 user_email 字段进行校验。注意此处必须使用 @classmethod,第一个参数是 cls(代表类本身),第二个参数 value 是传入的邮箱字符串。

check_total_amout() 的逻辑则体现了跨字段校验的特点:

  • 触发时机:在所有字段(包括 user_emailitems)都完成基础校验和转换之后才执行。
  • mode='after':这是 Pydantic V2 的新语法,表示在所有字段解析完成后执行。
  • self 参数:注意此处没有 @classmethod,它是一个实例方法。因为此时模型已初步构建,你可以直接通过 self.itemsself.total_amount 访问已转换好的对象属性。
来源:https://juejin.cn/post/7663396987304050688
上一篇Python基础全梳理:从注释到函数你掌握了吗? 下一篇Ubuntu系统全面JS日志分析实用技巧与最佳实践指南
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
Python for S60零基础入门指南与快速上手教程
编程语言 · 2026-07-18

Python for S60零基础入门指南与快速上手教程

PythonforS60是标准Python在诺基亚SymbianS60系统上的移植版本,旨在为移动开发者提供易学的脚本环境,以快速创建应用。它通过专用API访问摄像头、GPS等硬件,实现交互功能,显著降低了当时移动开发的门槛。尽管受限于性能、平台依赖而未能长久,但其推动移动开发便捷化的理念,在技术史上仍具启示意义。

Ubuntu LAMP支持哪些PHP版本
编程语言 · 2026-07-18

Ubuntu LAMP支持哪些PHP版本

Ubuntu不同LTS版本默认捆绑对应PHP版本,如22 04自带PHP8 1。若需其他版本,可通过OndřejSurý的PPA安装PHP5 6至8 2等版本,注意该PPA需手动添加并关注安全性。多版本共存时,可用update-alternatives工具切换默认PHP版本,并设置优先级顺序。建议定期更新PPA源以确保兼容性。

Ubuntu Node.js性能监控工具推荐
编程语言 · 2026-07-18

Ubuntu Node.js性能监控工具推荐

Ubuntu环境下Node js性能监控工具包括:PM2用于进程管理与实时监控;Prometheus与Grafana组合实现灵活的数据采集与可视化;NewRelic提供企业级全栈APM;Datadog支持云原生多环境监控;Easy-Monitor侧重故障定位与内存泄漏分析;Clinic js用于深度性能诊断;Heapdump与0x分别进行内存分析和火焰图生成

yum查看已安装软件列表方法
编程语言 · 2026-07-18

yum查看已安装软件列表方法

通过yumlistinstalled命令可列出所有已安装软件包及版本信息,配合grep过滤可查询特定软件;使用yuminfo可查看版本、仓库、描述等详细内容,是RHEL CentOS系统包管理常用操作。

Node.js日志归档最佳实践
编程语言 · 2026-07-18

Node.js日志归档最佳实践

Node js日志归档可用winston库实现日志分割、压缩、按天轮转及保留天数控制;也可用fs模块手工实现,但需自行处理日期比较与文件重命名,且易出错。生产环境推荐使用winston等成熟方案,稳定可靠。