跳转到内容

Python类型提示

typing 模块是 Python 在 PEP 484 中引入类型提示(Type Hints)后提供的官方标注支持库。其主要目的是配合外部工具进行静态代码分析(如使用 mypypyright 等进行类型检查)和辅助增强 IDE(如 VS Code、PyCharm)的代码补全和重构能力。


  • 普通使用示例
def test(a: int, b: str) -> str:
print(a, b)
return "1000"
  • 自定义类型别名
from typing import List
Vector = List[float]
def scale(scalar: float, vector: Vector) -> Vector:
return [scalar * num for num in vector]
# 静态类型检查器通过:float 列表符合 Vector 类型别名定义
new_vector = scale(2.0, [1.0, -4.2, 5.4])

3.1. 一、 集合与基本容器泛型 (Collections & Simple Types)

Section titled “3.1. 一、 集合与基本容器泛型 (Collections & Simple Types)”
typing 类型 (Python < 3.9)Python > = 3.9 原生支持语法说明解释
List[int]list[int]元素全为 int 类型的列表。
Dict[str, float]dict[str, float]键为 str、值为 float 的字典映射。
Set[bool]set[bool]元素全为 bool 类型的集合。
Tuple[str, int]tuple[str, int]包含且仅包含一个 str 和一个 int 的固定长度元组。
Tuple[int, ...]tuple[int, ...]元素全为 int 的未知任意长度元组。

3.2. 二、 关系与限定特殊类型 (Special Forms)

Section titled “3.2. 二、 关系与限定特殊类型 (Special Forms)”

声明变量的值可以兼容指定的多种不同类型之一。

typing 语法 (通用)Python >= 3.10 原生语法说明
Union[int, str]`intstr`

声明变量的值可以为指定类型,或者为空(None)。

typing 语法 (通用)Python >= 3.10 原生语法说明
Optional[str]`strNone`

代表不做类型限制。使用 Any 会导致静态类型检查器完全跳过针对该对象的语法校验。

from typing import Any
def process(data: Any) -> Any:
# 静态检查器会忽略对 data 对象的检查
return data

用于给函数、方法或支持 __call__ 的对象声明函数签名类型。

from typing import Callable, List
# 接收一个 int 参数,返回一个 str 的函数类型
Worker = Callable[[int], str]
def execute_task(func: Worker, value: int) -> str:
return func(value)
# 接收任意参数,并返回一个 List [str] 的函数(参数列表使用 ... 占位)
AnyParamFunc = Callable[..., List[str]]

用于表示 类定义本身(即类模板对象),而非该类的具体实例。

from typing import Type
class Base: pass
class Derived(Base): pass
# 参数 class_obj 期望传入 Base 类本身或其派生类,而非 Base 的实例对象
def create_instance(class_obj: Type[Base]) -> Base:
return class_obj()
# 静态类型检查通过
instance = create_instance(Derived)

用于定义泛型结构中的占位符。

from typing import TypeVar, List
# T 表示未知的泛型占位符
T = TypeVar('T')
def get_first_item(items: List[T]) -> T:
"""输入列表的元素类型与返回值类型在检查时保持完全一致"""
return items[0]
# 支持约束范围的类型变量
Number = TypeVar('Number', int, float) # 限制只能为 int 或 float 之一
def add_two(x: Number) -> Number:
return x + 2
# Python >= 3.12 推荐使用 type 关键字声明(更清晰)
type Coordinate = dict[str, int | float]
def get_coord(c: Coordinate):
pass

核心组件主要功能说明代码示例
NewType创建一个在语义上存在区分的独立类型。检查器会将其视为子类进行控制,防止误传。UserId = NewType('UserId', int)
Literal限制变量只能被赋予指定的某些特定字面值。Color = Literal['red', 'green', 'blue']
TypedDict限制字典必须具备固定的键(Key)且键对应的 Value 满足特定类型。class User(TypedDict): name: str; age: int
Protocol结构化子类型(支持静态的 Duck Typing)。实现该 Protocol 声明的方法即视为其子类,无需显式继承。class Runnable(Protocol): def run(self) -> None: ...
Final声明变量、方法或类 不应被重新赋值、方法重写或子类继承PI: Final[float] = 3.14159
NoReturn标注函数永远不会有 return 返回值(通常意味着函数必定会抛出异常或进入死循环)。def die() -> NoReturn: raise Exception()
TYPE_CHECKING静态检查运行期为 True,但在真实 Python 解释运行期为 False 的常量,常用于防止循环导入。if TYPE_CHECKING: from . import heavy_module

3.5. 五、 未来演进趋势 (Python 3.12+)

Section titled “3.5. 五、 未来演进趋势 (Python 3.12+)”

Python 的类型系统正在变得更加简洁,大量原本需要从 typing 导出的功能已经内置为系统级关键字:

  1. type 关键字 (PEP 695):声明类型别名无需再依赖赋值式代码。
  2. 泛型声明简化 (PEP 695):类定义中可以直接在类名后用 [T] 占位,免去了声明 Generic[T] 的冗长逻辑:
    • 旧版T = TypeVar('T'); class Box(Generic[T]): ...
    • 新版class Box[T]: ...
  3. @override 装饰器 (PEP 698):静态层级校验当前子类方法是否正确重写了父类方法。

3.5.1. 函数签名重载装饰器 @overload 综合实例

Section titled “3.5.1. 函数签名重载装饰器 @overload 综合实例”
from typing import overload, Union, List, Any
# 1. 声明重载签名一:输入 int,返回 int
@overload
def process_data(data: int) -> int:
...
# 2. 声明重载签名二:输入 str,返回 List [str]
@overload
def process_data(data: str) -> List[str]:
...
# 3. 声明重载签名三:输入 List [Any],返回 str
@overload
def process_data(data: List[Any]) -> str:
...
# 4. 实现的函数本体:其参数与返回值应兼容所有的重载约束,但运行时以此实现为准
def process_data(data: Union[int, str, List[Any]]) -> Union[int, List[str], str]:
if isinstance(data, int):
print("处理整数")
return data * 2
elif isinstance(data, str):
print("处理字符串")
return [data.upper()]
elif isinstance(data, list):
print("处理列表")
return ",".join(map(str, data))
else:
raise TypeError("不支持的类型")
# 静态类型检查器(如 Mypy)进行校验:
a: int = process_data(10) # 自动映射推断返回 int
b: List[str] = process_data("test") # 自动映射推断返回 List [str]
c: str = process_data([1, 2, "a"]) # 自动映射推断返回 str

4.1. ... (省略号/三点符) 的不同语境含义

Section titled “4.1. ... (省略号/三点符) 的不同语境含义”
场景语境说明示例
类型提示代表函数接受任意类型和数量的参数Callable[..., int]
类型提示代表元组可容纳任意个满足该类型的元素Tuple[int, ...]
科学计算NumPy 数组中代表省略多维切片的前置索引array[..., 0]
代码占位代替 pass 声明尚未编写具体实现的代码块def func(): ...
数据类dataclass 的 field 用作表示没有指定默认值field(default=...)
场景语境说明示例
逻辑运算按位或运算 (Bitwise OR)`x
集合操作两个 Set 集合合并求并集`set_a
字典操作两个 Dict 字典合并 (Python 3.9+)`dict_a
类型提示联合类型联合 (Union) (Python 3.10+)`int