Python 3.9起list、dict、set等内置类型原生支持泛型语法,可直接用list[int]、dict[str, int]等,无需导入typing.List等;str、int等非容器类型不支持泛型;泛型仅用于静态类型检查,运行时无效。

Python 3.9 中 list、dict、set 等直接当泛型用,不用再导入 typing.List
Python 3.9 起,内置集合类型原生支持泛型语法,这是最核心的变更。你不再需要从 typing 模块导入 List、Dict、Set、Tuple 或 Sequence —— 直接用 list[int]、dict[str, float] 就行。
常见错误是沿用旧写法却忘了删掉 from typing import List, Dict,导致类型检查器(如 mypy)报 error: "list" is not subscriptable(其实不是错误,是 Python 3.9+ 允许的;但若混用旧 import 和新语法,可能触发冗余警告或 IDE 误判)。
-
list[int]✅ 替代List[int](已弃用,3.9+ 不推荐) -
dict[str, int]✅ 替代Dict[str, int] -
set[float]✅ 替代Set[float] -
tuple[int, str, bool]✅ 固定长度元组;tuple[int, ...]表示变长元组 -
tuple[()]✅ 空元组(注意是tuple[()],不是tuple[])
哪些内置类型支持泛型?哪些不支持?
支持泛型的内置类型有:list、dict、set、frozenset、tuple、collections.deque、collections.defaultdict、collections.OrderedDict、collections.Counter。
不支持泛型的常见类型包括:str、bytes、int、float、bool —— 它们本身不是容器,无法参数化。试图写 str[int] 会直接报 SyntaxError: invalid syntax。
立即学习“Python免费学习笔记(深入)”;
-
deque[str]✅ 可用,但需确保运行环境是 Python 3.9+ -
defaultdict[str, int]✅ 可用,等价于collections.defaultdict[str, int] -
Counter[str]✅ 可用(collections.Counter是泛型类) -
Path[str]❌pathlib.Path不是泛型类,不能加方括号
函数参数和返回值里怎么写?注意运行时不可用
类型标注只是静态提示,Python 解释器在运行时不解析这些泛型参数。也就是说,list[int] 在运行时就是 list,isinstance(x, list[int]) 会报错 —— list[int] 不是真实类型,不能用于运行时检查。
- 函数签名中可放心写:
def process(items: list[str]) -> dict[str, int]: ... - 不要在
isinstance()、type()或__annotations__反射中依赖泛型结构(比如__annotations__["items"]返回的是list[str]这个 AST 对象,不是可调用类型) - 若需运行时类型验证,得用第三方库如
typeguard或手写检查逻辑
和旧版代码共存时要注意什么?
如果你的项目要兼容 Python 3.8 及以下,就不能直接用 list[str],否则解释器会报 SyntaxError。此时必须继续用 typing.List[str] 并保持 from typing import List。
Python 3.9+ 兼容旧写法(List[str] 仍能被 mypy/pyright 识别),但官方文档明确标记为“deprecated”,且未来版本可能移除。
- 跨版本项目建议:用字符串字面量标注,例如
def f() -> "list[int]": ...,避免语法错误 - 使用
if sys.version_info >= (3, 9):动态导入不是好办法——类型检查器看不到条件分支里的 import,会导致标注失效 - mypy 默认对 3.9+ 启用新语法;若误设
--python-version 3.8,它会拒绝list[str]
真正容易被忽略的是:泛型参数不参与运行时行为,也不影响性能。写 list[int] 不会让列表变快或变慢,它只服务于工具链 —— 所以别为了“看起来更类型安全”而堆砌嵌套泛型,比如 list[dict[str, list[Optional[float]]]],可读性和维护成本会陡增。


















