python 3.10+ 中 | 是类型系统底层变更(pep 604),非语法糖,仅限类型标注使用;运行时需用 union 或元组,isinstance 等不支持 |,optional[t] 语义更明确,推荐优先使用。

因为 Python 3.10+ 的 | 不是语法糖,而是类型系统底层变更(PEP 604),它更短、无需导入、嵌套清晰,且 Union 已被官方弃用。
运行时和静态检查中 | 与 Union 的行为差异
两者语义等价,但底层对象不同:int | str 在 Python 3.10+ 中生成 types.UnionType 实例,而 Union[int, str] 生成的是 typing.Union 类型(已在 3.10+ 标记为弃用)。mypy、pyright 等工具默认对后者发出 DeprecationWarning 或 error,尤其在 Union[T, None] 场景下会明确提示 “Use 'T | None' instead”。
-
isinstance(x, int | str)会报错:运行时|不产生可被isinstance接受的类型元组,必须写成isinstance(x, (int, str)) -
get_type_hints()对|的解析结果依赖于是否启用from __future__ import annotations和 Python 版本,可能统一转为Union对象 - IDE 补全(如 Pylance)在识别
int |后可能不自动提示右侧类型,需确认项目 Python 版本配置正确
哪些地方必须用 |,哪些仍得保留 Union
| 只在类型标注(type annotation)上下文中合法;所有运行时类型操作、反射或旧环境兼容场景,仍需 Union。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- ✅ 安全用
|:函数参数、返回值、变量注解,例如def load(path: str | bytes | os.PathLike) -> dict | None: - ❌ 不能用
|:运行时判断(isinstance(x, int | str))、构造类型别名用于getattr或Union.__args__反射、与 mypy - ⚠️ 可读性优先时保留
Union:嵌套过深如Union[list[dict[str, int | None]], tuple[str, ...]],分行写Union[...]更易维护
Optional[T] 能不能直接换成 T | None
技术上可以,但语义和工具链支持有差别。推荐继续用 Optional[T] 表达“可选值”,尤其在函数返回类型中。
-
Optional[str]是类型检查器的“语义开关”:mypy 会据此推导默认值为None,并强制要求判空(if s is not None:)后才允许访问属性 -
str | None更偏向“类型并集”,部分检查器可能弱化判空提示,且 IDE hover 提示里会显示 “PreferOptional[str]” - 若项目已全面启用 PEP 604,且团队接受风格统一,
str | None也可接受——但不要混用,否则 mypy 可能报inconsistent-union
真正容易被忽略的点是:| 的合法性只存在于 AST 解析阶段,它不参与运行时逻辑;一旦你试图把它当普通表达式用(比如赋给变量再传入函数做类型构造),就会触发 TypeError 或 AttributeError。写之前先问一句:这行代码是在注解里,还是在执行流里?
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










