Pydantic BaseModel 入门教程
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 验证器,大幅提升效率。

核心验证架构: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',所有未定义的额外字段会被安全收纳到这里,确保数据不丢失。
实战案例:从基础到进阶
基础操作示例
- 基础操作:访问模型数据
复制代码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}")
- 防止字段隐式转换:配置严格模式
复制代码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
- 序列化与反序列化:数据转换与恢复
复制代码# 序列化
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'
- 增加字段、查看原有字段:灵活扩展模型
复制代码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'}
进阶应用技巧
- 增加字段复杂度,如嵌套数据结构
复制代码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}")
- 模型继承,共享相同字段:复用基础结构
复制代码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
- 树形递归结构:处理层级数据模型
复制代码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)])]
- 字段约束:精细化数据规则
复制代码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="产品价格")
- 自定义业务逻辑校验
复制代码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_email和items)都完成基础校验和转换之后才执行。 mode='after':这是 Pydantic V2 的新语法,表示在所有字段解析完成后执行。self参数:注意此处没有@classmethod,它是一个实例方法。因为此时模型已初步构建,你可以直接通过self.items和self.total_amount访问已转换好的对象属性。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
Python for S60零基础入门指南与快速上手教程
PythonforS60是标准Python在诺基亚SymbianS60系统上的移植版本,旨在为移动开发者提供易学的脚本环境,以快速创建应用。它通过专用API访问摄像头、GPS等硬件,实现交互功能,显著降低了当时移动开发的门槛。尽管受限于性能、平台依赖而未能长久,但其推动移动开发便捷化的理念,在技术史上仍具启示意义。
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性能监控工具推荐
Ubuntu环境下Node js性能监控工具包括:PM2用于进程管理与实时监控;Prometheus与Grafana组合实现灵活的数据采集与可视化;NewRelic提供企业级全栈APM;Datadog支持云原生多环境监控;Easy-Monitor侧重故障定位与内存泄漏分析;Clinic js用于深度性能诊断;Heapdump与0x分别进行内存分析和火焰图生成
yum查看已安装软件列表方法
通过yumlistinstalled命令可列出所有已安装软件包及版本信息,配合grep过滤可查询特定软件;使用yuminfo可查看版本、仓库、描述等详细内容,是RHEL CentOS系统包管理常用操作。
Node.js日志归档最佳实践
Node js日志归档可用winston库实现日志分割、压缩、按天轮转及保留天数控制;也可用fs模块手工实现,但需自行处理日期比较与文件重命名,且易出错。生产环境推荐使用winston等成熟方案,稳定可靠。
- 热门数据榜
相关攻略
2026-07-18 22:34
2026-07-18 22:33
2026-07-18 22:33
2026-07-18 22:33
2026-07-18 22:33
2026-07-18 22:10
2026-07-18 22:10
2026-07-18 22:09
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程

