Python 的类型提示系统提供了一种标准化的方式来指示 Python 代码中变量、函数参数和返回值的类型。本文档描述了 CPython 解释器中 Python 类型提示系统的实现细节,重点关注其结构、类型提示在内部的表示方式以及它们在运行时如何被处理。
类型提示系统主要通过 typing 模块实现,该模块提供了定义类型提示的核心构造,以及较新的 annotationlib 模块,该模块提供了用于自省和处理注解的工具。虽然类型提示本身不会影响 Python 代码的运行时行为(Python 仍然是动态类型的),但它们提供了元数据,可供静态类型检查器、IDE 和文档生成器等外部工具使用。
有关类型提示系统所构建的更广泛的对象系统的更多信息,请参阅 PyObject 和类型系统。
Python 的类型注解系统经历了几个阶段的演变,每个阶段在注解的处理方式上都有不同的语义。
from __future__ import annotations):注解被存储为字符串,而不进行评估。来源:Doc/library/annotationlib.rst67-96 Lib/annotationlib.py47-102 Lib/_collections_abc.py1-33
类型提示系统由多个关键组件协同工作而成
来源:Lib/typing.py1-20 Lib/annotationlib.py1-19 Lib/_collections_abc.py1-33
类型提示系统围绕几个关键组件构建,它们协同工作以提供一个全面的类型注解框架。
typing 模块提供了类型提示的基本原语。
| 组件 | 描述 | 示例 |
|---|---|---|
TypeVar | 泛型函数和类的类型变量 | T = TypeVar('T') |
任意 | 表示无约束类型的特殊类型 | def func(x: Any) -> int: ... |
Union | 联合类型(X 或 Y) | Union[str, int] 或 str | int |
可选 | 可选类型(X 或 None) | Optional[str] 或 str | None |
通用 | 用户定义泛型类的基类 | class Stack(Generic[T]): ... |
协议 | 协议定义的基类 | class Sized(Protocol): ... |
可调用对象 | 可调用对象的类型 | Callable[[int, str], bool] |
来源:Lib/typing.py44-162 Doc/library/typing.rst207-276
typing 模块包含在类型提示中具有特殊含义的特殊形式。
来源:Lib/typing.py513-684 Doc/library/typing.rst714-756
类型变量是泛型类型化的基石。它们表示可变动的类型,允许在类型定义中实现参数化多态。
类型变量的创建可以带有各种选项来修改其行为。
来源:Lib/typing.py380-617 Lib/test/test_typing.py380-811
泛型别名表示参数化的容器类型。当泛型类被特定类型参数下标时,就会创建它们。
泛型别名系统与 Python 内置的 __class_getitem__ 机制深度集成,允许内置类型和自定义类都用作泛型类型。
来源:Lib/typing.py260-349 Doc/library/typing.rst301-440
前向引用允许注解引用尚未定义的类型。ForwardRef 类处理这些引用。
前向引用是在处理字符串注解时自动创建的,也可以显式创建。它们在注解被访问时(通常通过 get_type_hints())进行解析(评估)。
来源:Lib/annotationlib.py49-251 Lib/typing.py172-250
可以通过几种机制访问注解。
annotationlib 模块提供了几个处理注解的实用工具。
| 功能 | 描述 |
|---|---|
get_annotations(obj, *, format=Format.VALUE) | 获取具有格式控制的注解。 |
get_annotate_function(obj) | 获取生成注解的函数。 |
call_annotate_function(func, format) | 使用特定格式调用注解函数。 |
type_repr(obj) | 获取类型的字符串表示。 |
来源:Lib/annotationlib.py392-692 Doc/library/annotationlib.rst115-145
annotationlib 中的 Format 枚举定义了注解可以返回的格式。
来源:Lib/annotationlib.py22-26 Doc/library/annotationlib.rst118-141
类型提示不会直接影响运行时行为——Python 在运行时仍然是动态类型的。但是,它们在运行时确实具有存在性。
Python 的运行时不强制执行类型注解,但提供了访问它们的 API,这使得
来源:Doc/library/typing.rst11-22 Lib/test/test_type_annotations.py11-136
协议在 Python 中实现了结构化类型,侧重于对象支持的方法,而不是其继承层级。
协议定义了一个接口,类必须满足该接口才能被视为兼容,而无需显式继承。
来源:Doc/library/typing.rst254-276 Lib/_collections_abc.py110-170
类型提示系统与 Python 的核心对象系统集成。
类型提示存储在类、函数和模块的 __annotations__ 字典中,或者由存在的 __annotate__ 方法生成。
来源: Lib/test/test_type_annotations.py10-101 Include/internal/pycore_global_strings.h226-227
Python 的类型提示系统提供了一个丰富、灵活的框架,用于在 Python 代码中添加类型信息。虽然这些提示在运行时不强制执行,但它们支持广泛的静态分析、文档和代码理解工具。该系统多年来经历了重大发展,最新的进展侧重于延迟评估注解以提高性能和支持前向引用。
类型提示是动态和静态类型之间的一座重要桥梁,它允许 Python 在保持其动态特性的同时,在需要时提供静态类型检查的好处。