Python @dataclass 使用说明
@dataclass 是 Python 标准库 dataclasses 提供的装饰器,用来快速定义“主要用于保存数据的类”。
它可以自动生成 __init__、__repr__、__eq__ 等常用方法,让代码更简洁。
1. 为什么需要 @dataclass
如果不用 @dataclass,定义一个保存配置的类通常需要手写 __init__:
class Context:
def __init__(self, model, model_provider):
self.model = model
self.model_provider = model_provider使用 @dataclass 后,可以简化为:
from dataclasses import dataclass
@dataclass
class Context:
model: str
model_provider: strPython 会自动帮你生成初始化方法,所以可以直接这样创建对象:
context = Context(
model="qwen3.5-plus",
model_provider="openai",
)2. 基本语法
from dataclasses import dataclass
@dataclass
class User:
name: str
age: int创建对象:
user = User(name="Alice", age=18)
print(user)输出类似:
User(name='Alice', age=18)3. 字段类型标注
@dataclass 通常和类型标注一起使用,支持 Python 所有内置和标准库类型。
基本类型
from dataclasses import dataclass
@dataclass
class Product:
name: str # 字符串
price: float # 浮点数
stock: int # 整数
on_sale: bool # 布尔值List / Dict / Tuple / Set
from dataclasses import dataclass, field
from typing import List, Dict, Tuple, Set
@dataclass
class Order:
items: List[str] # 字符串列表
quantities: Dict[str, int] # 字符串到整数的字典
tags: Set[str] # 字符串集合
coordinates: Tuple[float, float] # 固定长度的元组注意:List、Dict 等默认值不能直接写 = [],要用 field(default_factory=...):
@dataclass
class Order:
items: List[str] = field(default_factory=list)
metadata: Dict[str, str] = field(default_factory=dict)Python 3.9+ 内置写法(不需要 import typing)
@dataclass
class Order:
items: list[str] # 等价于 List[str]
metadata: dict[str, int] # 等价于 Dict[str, int]
tags: set[str] # 等价于 Set[str]可选类型
from dataclasses import dataclass
@dataclass
class Config:
api_key: str | None = None # 可以是 str,也可以是 None(Python 3.10+)
base_url: str | None = NonePython 3.9 及以下用 Optional:
from typing import Optional
@dataclass
class Config:
api_key: Optional[str] = None嵌套 dataclass
@dataclass
class Address:
city: str
country: str
@dataclass
class User:
name: str
age: int
address: Address # 嵌套另一个 dataclass使用:
user = User(
name="Alice",
age=18,
address=Address(city="Beijing", country="China"),
)
print(user.address.city) # Beijing综合示例
from dataclasses import dataclass, field
from typing import List, Dict
@dataclass
class ModelConfig:
model: str # 必填字符串
temperature: float = 0.7 # 浮点数带默认值
max_tokens: int = 1024 # 整数带默认值
stop_sequences: List[str] = field(default_factory=list) # 字符串列表
extra_params: Dict[str, str] = field(default_factory=dict) # 字典
api_key: str | None = None # 可选字符串类型标注主要用于代码提示、静态检查和可读性,不会默认强制运行时类型校验。
4. 默认值
字段可以设置默认值:
@dataclass
class Config:
model: str
temperature: float = 0.7
max_tokens: int = 1024使用时可以只传必填字段:
config = Config(model="qwen3.5-plus")
print(config.temperature) # 0.7注意:没有默认值的字段要写在有默认值字段的前面。
5. 可选字段
如果一个字段可以是字符串,也可以为空,可以这样写:
@dataclass
class Context:
api_key: str | None = None
base_url: str | None = None含义是:
api_key可以是str,也可以是None- 默认值是
None
6. 当前代码中的用法
在 5.configurable_model.py 中,Context 用来保存运行时模型配置:
@dataclass
class Context:
model: str
model_provider: str
api_key: str | None = None
base_url: str | None = None它表示一次 Agent 调用时可以传入这些信息:
model:模型名称,例如"qwen3.5-plus"model_provider:模型提供方,例如"openai"api_key:模型服务的 API Keybase_url:模型服务的接口地址
调用时可以这样传入:
context = Context(
model="qwen3.5-plus",
model_provider="openai",
api_key=DASHSCOPE_API_KEY,
base_url=DASHSCOPE_BASE_URL,
)然后中间件可以通过 request.runtime.context 读取这些配置:
context = request.runtime.context
model = init_chat_model(
context.model,
model_provider=context.model_provider,
api_key=context.api_key,
base_url=context.base_url,
)这样就能在运行时动态切换模型。
7. @dataclass 自动生成了什么
定义:
@dataclass
class User:
name: str
age: int大致等价于自动生成:
class User:
def __init__(self, name: str, age: int):
self.name = name
self.age = age
def __repr__(self):
return f"User(name={self.name!r}, age={self.age!r})"
def __eq__(self, other):
return self.name == other.name and self.age == other.age所以 @dataclass 可以减少大量模板代码。
8. 常见适用场景
@dataclass 适合用来定义结构化数据:
- 配置对象
- 请求上下文
- 用户信息
- 商品信息
- 任务参数
- 中间状态
- API 返回结果的数据结构
例如:
@dataclass
class TaskConfig:
task_id: str
model: str
timeout: int = 309. 什么时候不适合用 @dataclass
如果一个类主要负责复杂行为,而不是保存数据,就不一定适合使用 @dataclass。
例如:
- 需要复杂初始化逻辑
- 需要继承复杂框架基类
- 主要封装业务行为
- 需要严格运行时校验
这类场景可能更适合普通类,或者使用 Pydantic 这类数据校验库。
10. 小结
@dataclass 可以理解为:
用更少的代码定义一个清晰的数据容器类。
它最常见的价值是:
- 自动生成初始化方法
- 自动生成可读的打印结果
- 减少重复代码
- 让配置和上下文对象更清晰
在当前 LangChain 示例中,Context 使用 @dataclass 是为了方便保存并传递运行时模型配置。
最后编辑:海马 更新时间:2026-07-01 20:05