在 Python 中,TypedDict 是官方在 Python 3.8 引入的一个类型注解工具(位于 typing 模块中)。
简单来说:它本质上就是一个普通的 Python 字典(dict),但它在代码编写和静态检查阶段,具有像类(Class)一样的键名(Key)和键值(Value)类型约束。
1. 为什么需要 TypedDict?
在没有 TypedDict 之前,如果你给一个字典加类型提示:
python
user: dict[str, str] = {"name": "Alice", "role": "admin"}
问题在于:
- 它只能规定所有的 Key 是
str,所有的 Value 是str。 - 它无法规定这个字典必须包含哪些特定的键 (比如必须有
"name"和"age")。 - 如果 Value 类型不一致(比如
name是str,age是int),你只能写dict[str, Any],这样就彻底丢失了类型检查和 IDE 的自动补全。
2. TypedDict 长什么样?
使用 TypedDict,你可以像定义类一样定义字典的"形状"(Schema):
python
from typing import TypedDict
# 定义字典的数据结构
class UserState(TypedDict):
user_id: int
user_name: str
is_active: bool
# 实例化:它本质上就是一个标准 dict!
user: UserState = {"user_id": 101, "user_name": "Alice", "is_active": True}
# 运行时检验:
print(type(user)) # 输出: <class 'dict'>,没有任何类实例化的额外开销!
它的好处:
- IDE 代码自动补全 :当你输入
user["时,编辑器会直接提示补全user_id、user_name等。 - 静态类型检查(MyPy / Pyright) :如果你写错拼写(例如
user["username"])或者传入了错误类型(user["user_id"] = "abc"),静态类型检查器和 VSCode/PyCharm 会直接标红报错。
3. 它与 LangGraph / 前文上下文的关系
在 LangGraph 中,图(Graph)在节点之间传递的数据载体就叫做 State(状态)。
LangGraph 官方标准做法就是用 TypedDict 来定义这个 State:
python
from typing import TypedDict
from langgraph.graph import END, START, StateGraph
# 1. 用 TypedDict 约束图里流动的数据结构
class TranslationState(TypedDict):
input_text: str
target_language: str
translated_text: str # 后续节点会填入这个字段
# 2. 定义图节点
def translate_node(state: TranslationState) -> dict:
# 这里能享受 IDE 的完美补全和类型保护
text = state["input_text"]
target = state["target_language"]
# ... 调用 LLM ...
return {"translated_text": "你好,世界"}
# 3. 构建图
builder = StateGraph(TranslationState)
builder.add_node("translate", translate_node)
builder.add_edge(START, "translate")
builder.add_edge("translate", END)
graph = builder.compile()
4. 它和 Pydantic 的区别(为什么前文两者都提到了?)
前文提到:"with typed state in and a typed Pydantic result out"(输入是强类型的 TypedDict 状态,输出是强类型的 Pydantic 结果)。它们的分工是不同的:
| 特性 | TypedDict |
Pydantic (BaseModel) |
|---|---|---|
| 底层本质 | 就是普通 Python 原生字典 dict |
一个独立的自定义类实例(Class Object) |
| 运行时验证 | 无(只在写代码和静态检查时起作用,运行几乎零性能损耗) | 有(运行时会进行严格的数据解析、类型转换和校验) |
| 常见用途 | 框架内部管线传参(如 LangGraph 的状态流转) | 接口入参校验、LLM 结构化输出(让模型吐出合法 JSON) |
总结: 前文作者的意思是:LangGraph 内部流转的状态数据用了 TypedDict (既有类型提示与补全规范,又像普通字典一样轻量零开销);而让 LLM 输出的结构化数据则用 Pydantic 进行严格的运行时格式校验。