Python/pydantic
外觀
< Python
pydantic是一個具有高級功能的Python的數據容器和數據驗證的第三方包。
安裝
[編輯]pip install pydantic
基礎用法
[編輯]from pydantic import BaseModel
class Student(BaseModel):
name: str
age: int
grade: float
is_active: bool = True
layers: List[int] = [128, 64] # ✅ 初始化安全:每个实例都是新列表
# ✅ 正常创建
student = Student(name="张三", age=20, grade=85.5)
print(student)
# name='张三' age=20 grade=85.5 is_active=True
# ✅ 自动类型转换
student2 = Student(name="李四", age="22", grade="90.0")
print(student2.age) # 22 (int) - 从字符串自动转换
print(type(student2.age)) # <class 'int'>
數據驗證
[編輯]from pydantic import BaseModel, ValidationError
class Student(BaseModel):
name: str
age: int
grade: float
# ❌ 验证失败
try:
student = Student(name=123, age="不是数字", grade=85.5)
except ValidationError as e:
print(e)
輸出:
2 validation errors for Student name Input should be a valid string [type=string_type, input_value=123, input_type=int] age Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='不是数字', input_type=str]
高級驗證
[編輯]from pydantic import BaseModel, Field, field_validator, EmailStr
from typing import Annotated
class User(BaseModel):
# 字段级验证
username: str = Field(min_length=3, max_length=20, pattern=r'^[a-zA-Z0-9_]+$')
age: Annotated[int, Field(gt=0, lt=150)] # 0 < age < 150
email: EmailStr # 自动验证邮箱格式
score: float = Field(ge=0.0, le=100.0) # 0 <= score <= 100
# 自定义验证器
@field_validator('username')
@classmethod
def username_must_be_lowercase(cls, v: str) -> str:
if not v.islower():
raise ValueError('用户名必须是小写字母')
return v
# ✅ 验证通过
user = User(username="zhangsan", age=25, email="zhangsan@example.com", score=85.5)
# ❌ 验证失败
try:
user = User(username="ab", age=200, email="invalid", score=150)
except ValidationError as e:
print(e)
# username: 至少3个字符
# age: 必须小于150
# email: 邮箱格式错误
# score: 必须小于等于100
JSON 序列化
[編輯]from pydantic import BaseModel
from pathlib import Path
from datetime import datetime
class Experiment(BaseModel):
name: str
data_path: Path
created_at: datetime
parameters: dict
exp = Experiment(
name="实验001",
data_path="/data/exp001",
created_at="2024-01-15T10:30:00",
parameters={"learning_rate": 0.001, "epochs": 100}
)
# 转为字典
print(exp.model_dump())
# {
# 'name': '实验001',
# 'data_path': PosixPath('/data/exp001'),
# 'created_at': datetime.datetime(2024, 1, 15, 10, 30),
# 'parameters': {'learning_rate': 0.001, 'epochs': 100}
# }
# 转为 JSON 字符串
print(exp.model_dump_json(indent=2))
# {
# "name": "实验001",
# "data_path": "/data/exp001",
# "created_at": "2024-01-15T10:30:00",
# "parameters": {
# "learning_rate": 0.001,
# "epochs": 100
# }
# }
# 从 JSON 加载
json_str = '{"name": "实验002", "data_path": "/data/exp002", "created_at": "2024-01-16T11:00:00", "parameters": {}}'
exp2 = Experiment.model_validate_json(json_str)
print(exp2.name) # 实验002
嵌套模型
[編輯]from pydantic import BaseModel
from typing import List
class Address(BaseModel):
street: str
city: str
country: str
class Company(BaseModel):
name: str
address: Address
class Employee(BaseModel):
name: str
age: int
company: Company
skills: List[str]
# 创建嵌套对象
employee = Employee(
name="张三",
age=30,
company={
"name": "科技公司",
"address": {
"street": "中关村大街1号",
"city": "北京",
"country": "中国"
}
},
skills=["Python", "机器学习", "数据分析"]
)
print(employee.company.address.city) # 北京
print(employee.model_dump_json(indent=2))
配置選項
[編輯]from pydantic import BaseModel, ConfigDict
class StrictModel(BaseModel):
model_config = ConfigDict(
str_strip_whitespace=True, # 自动去除字符串首尾空格
validate_assignment=True, # 赋值时也验证
frozen=True, # 不可变对象
extra='forbid' # 禁止额外字段
)
name: str
age: int
# ✅ 自动去除空格
model = StrictModel(name=" 张三 ", age=25)
print(model.name) # "张三"
# ❌ 不可变
# model.age = 30 # ValidationError
# ❌ 禁止额外字段
try:
model = StrictModel(name="李四", age=30, extra_field="不允许")
except ValidationError as e:
print(e) # Extra inputs are not permitted