Python类型提示系统
原文:typing 类型标注
一句话
Python类型提示系统,用于静态类型检查和代码文档。
什么时候翻这页
- 需要为函数和类添加类型提示以提高代码可读性
- 使用泛型类型创建灵活的数据结构
- 定义协议(Protocol)实现结构化输出,用于Agent工具返回类型
- 标注异步函数和生成器,用于处理Agent的异步操作
核心概念
- 类型别名:使用
type关键字或TypeAlias为复杂类型创建简短名称 - NewType:创建特定类型的新子类型,增强类型安全性
- 泛型(Generic):使用
TypeVar创建可重用的类型参数化类和函数 - 协议(Protocol):定义结构化接口,用于实现鸭子类型
- 特殊类型:如
Any、Union、Literal等用于特殊场景的类型 - 类型守卫和类型收窄:使用
TypeGuard和TypeIs进行类型检查和收窄 - 参数规范(ParamSpec):用于标注可变参数和关键字参数的类型
怎么做
- 基本类型标注:
def surface_area_of_cube(edge_length: float) -> str:
return f"The surface area of the cube is {6 * edge_length ** 2}."
- 创建类型别名:
type Vector = list[float]
def scale(scalar: float, vector: Vector) -> Vector:
return [scalar * num for num in vector]
- 使用NewType创建特定类型:
from typing import NewType
UserId = NewType('UserId', int)
some_id = UserId(524313)
def get_user_name(user_id: UserId) -> str:
return f"User {user_id}"
- 定义泛型类:
from typing import TypeVar, Generic
T = TypeVar('T')
class LoggedVar(Generic[T]):
def __init__(self, value: T, name: str) -> None:
self.value = value
self.name = name
def set(self, new: T) -> None:
print(f"Setting {self.name} from {self.value} to {new}")
self.value = new
def get(self) -> T:
print(f"Getting {self.name}: {self.value}")
return self.value
- 定义协议:
from typing import Protocol
class Combiner(Protocol):
def __call__(self, *vals: bytes, maxlen: int | None = None) -> list[bytes]: ...
def batch_proc(data: list[bytes], cb_results: Combiner) -> bytes:
# 处理数据
pass
- 标注异步函数:
from collections.abc import AsyncGenerator
async def infinite_stream(start: int) -> AsyncGenerator[int]:
while True:
yield start
start += 1
命令 / API 速查
| 类型/函数 | 描述 |
|---|---|
Any | 表示任意类型 |
Union[X, Y] | 表示X或Y类型 |
Optional[X] | 表示X或None类型 |
List[X] | 表示X类型的列表 |
Dict[K, V] | 表示键为K类型,值为V类型的字典 |
Tuple[X, Y] | 表示X和Y类型的元组 |
Callable[[X], Y] | 表示接受X类型参数并返回Y类型的可调用对象 |
Generator[X, Y, Z] | 表示生成器,产生X类型,接受Y类型,返回Z类型 |
AsyncGenerator[X, Y] | 表示异步生成器 |
Protocol | 定义协议接口 |
TypeVar | 定义类型变量 |
NewType | 创建新类型 |
TypeGuard | 类型守卫函数 |
TypeIs | 类型判断函数 |
ParamSpec | 参数规范类型变量 |
Concatenate | 连接参数规范 |
Final | 标记不可重写或不可重新赋值的属性 |
ClassVar | 标记类变量 |
Literal | 表示字面值类型 |
TypedDict | 表示类型化字典 |
Annotated | 带有额外元数据的类型 |
assert_type | 断言变量为特定类型 |
reveal_type | 显示变量的推断类型 |
cast | 类型转换 |
get_type_hints | 获取对象的类型提示 |
get_origin | 获取类型的原始类型 |
get_args | 获取类型的参数 |
与 Agent 开发的联系
- 工具返回类型标注:使用
TypedDict和Protocol为Agent工具定义结构化返回类型,确保返回的数据符合预期格式 - 异步操作处理:使用
AsyncGenerator和Awaitable标注Agent的异步操作,如流式响应处理 - 类型安全工具调用:通过类型提示确保Agent工具调用的参数类型正确,减少运行时错误
初学者易错点
- 混淆类型变量和具体类型:
TypeVar是类型变量,不是具体类型,不能直接用作类型注解 - 过度使用
Any:虽然Any很方便,但过度使用会失去类型检查的好处 - 忽略类型守卫的作用域:
TypeGuard和TypeIs只在函数内部有效,不会改变外部变量的类型 - 错误使用泛型约束:泛型约束(
bound,covariant,contravariant)使用不当会导致类型检查错误 - 前向引用未正确处理:在类定义中使用尚未定义的类型时,需要使用字符串形式或
ForwardRef
相关词条
library-dataclasses- 数据类,与类型提示结合使用library-contextlib- 上下文管理器,与类型提示结合使用library-asyncio- 异步编程,与类型提示结合使用library-json- JSON数据处理,与类型提示结合使用library-pydantic- 数据验证库,基于类型提示library-mypy- 静态类型检查器