主题
04 · 类、类型注解与 Pydantic
为什么要学类?
SDK 经常这样写:client = OpenAI(...),随后 client.chat.completions.create(...)。你不需要先设计复杂面向对象系统,但要理解「类创建实例,实例携带状态和方法」。
python
class Counter:
def __init__(self, initial: int = 0): # 类似 constructor
self.value = initial # 类似 this.value
def increment(self):
self.value += 1
counter = Counter(3)
counter.increment()
print(counter.value) # 4self 相当于实例自身,普通实例方法的第一个参数必须写它;调用时 Python 会自动传入。
Agent 常见类型注解
python
from typing import Literal, TypedDict
class Message(TypedDict):
role: Literal["system", "user", "assistant"]
content: str
messages: list[Message] = [{"role": "user", "content": "你好"}]
result: str | None = None # 类似 TS 的 string | nulllist[str]:字符串列表。dict[str, int]:键是字符串,值是整数。str | None:可能为空。Literal[...]:枚举式字面量类型。TypedDict:为普通 dict 提供形状声明,不会验证运行时数据。
Pydantic:可以运行的 Schema
你熟悉 Zod 的话,可以把 Pydantic 理解为 Python 的「Schema 校验 + 数据对象 + JSON Schema 生成」工具。
bash
uv add "pydantic>=2,<3"python
from pydantic import BaseModel, Field, ValidationError
class WeatherArgs(BaseModel):
city: str = Field(min_length=1, description="城市名称")
days: int = Field(default=1, ge=1, le=7, description="预报天数")
args = WeatherArgs.model_validate({"city": "北京", "days": 3})
print(args.city) # 北京
print(args.model_dump()) # 转成 dict
print(args.model_dump_json()) # 转成 JSON 文本
print(WeatherArgs.model_json_schema()) # 给大模型看的 JSON Schema
try:
WeatherArgs(city="北京", days=30)
except ValidationError as error:
print(error.errors()[0]["type"]) # less_than_equal这里的 ge 表示大于等于,le 表示小于等于。请注意:Field 的 description 是给人和模型看的,约束才是程序执行的。
默认会进行部分类型转换
例如字符串 "3" 可能被转换为整数 3。安全敏感参数可以使用 model_validate(data, strict=True),拒绝宽松转换。无论使用哪种模式,都要在工具执行前校验。
装饰器:先把它读懂
你会看到这样的语法:
python
from functools import wraps
def trace(fn):
@wraps(fn)
def wrapped(*args, **kwargs):
print(f"调用 {fn.__name__}")
return fn(*args, **kwargs)
return wrapped
@trace
def add(a, b):
return a + b
print(add(1, 2))@trace 大致等价于定义函数后执行 add = trace(add)。在 FastAPI 中 @app.post(...) 注册路由,在 MCP 中 @mcp.tool() 注册工具。装饰器不一定返回包装函数,也可能仅做注册;先记住「把函数交给另一个函数处理」即可。
动手练习
定义 Task 模型:title 非空字符串,priority 只能是 low / medium / high,done 默认 False。验证一条有效数据和一条非法优先级数据。
参考答案
python
from typing import Literal
from pydantic import BaseModel, Field, ValidationError
class Task(BaseModel):
title: str = Field(min_length=1)
priority: Literal["low", "medium", "high"] = "medium"
done: bool = False
print(Task(title="学习 Python").model_dump())
try:
Task(title="测试", priority="urgent")
except ValidationError:
print("非法优先级已被拒绝")检查点:类型注解与 Pydantic 校验之间的区别是什么?模型调用工具时,应该信任参数的类型声明,还是在运行时再验证一次?