Python 3.10+ 的 | 它是原生联合类型运算符,只在类型注释中合法,不能用于运行 isinstance 或反射;Union 弃用但仍是动态操作的唯一选择。
| 是 Python 3.10+ 类型系统原生支持的运算符(PEP 604),不是语法糖,直接参与 AST 解析,生成 types.UnionType 实例;而 Union 类型检查器已被标记为弃用(如 mypy 0.950+、pyright)默认报 warning 或 error。
操作时不能使用 | 做类型判断
写 isinstance(x, int | str) 会直接抛 TypeError: isinstance() arg 2 must be a type or tuple of types。因为 | 在运行过程中不产生可被 isinstance 接受元组或类型对象。
- 正确的写法只能是
isinstance(x, (int, str)) - 如果需要动态结构联合类型进行反射(如读取)
Union.__args__),必须用from typing import Union,不能用| -
type_union = int | str然后将函数传输到类型操作中,大概率触发AttributeError或TypeError
| 只在类型标注上下文中合法
它只在函数签名、变量注释、类属性等 AST 类型注释位置有效,其他地方使用错误。
- ✅ 允许:
def f(x: str | bytes) -> dict[str, int] | None: - ❌ 禁止:
if x is None or isinstance(x, str | bytes): - ⚠️ 危险:
alias = str | int然后试图getattr(alias, '__args__')——types.UnionType没有__args__属性
Union 和 | 的处理差异
工具链对两者的底层表示不同,导致行为不一致:
Python 3.14.2
Python 3.14.2是Python编程语言于2025年12月5日发布的稳定版本,属于3.14系列的第二次维护更新。该版本包含18个修复项目,重点解决多过程、数据和正则表达模块的回归问题,修复CVE-2025-12084等安全漏洞。这个版本标志着Python发展的一个重要里程碑,即自由线程模式(删除GIL)正式得到官方支持。
下载- mypy 默认把
str | int视为等价于Union[str, int],但会拒绝Union[str, None]并提示 “Use 'str | None' instead” - pyright 在一些泛型嵌套场景(如
List[str | int])可能会报错,但是List[Union[str, int]]反而通过 - IDE 补全依赖 Python 版本配置:PyCharm/Pylance 若未识别的项目为 3.10+,输完
int |后续类型不提示 -
get_type_hints()在返回结果中,|可以标准化形式Union具体取决于对象是否启用。from __future__ import annotations和 Python 版本
|
简单联合(如 int | str | None)用 | 更清晰;但当嵌套太深时,括号和缩进很容易出错,反而降低了可维护性。
立即学习“Python免费学习笔记(深入);
- 难读示例:
list[dict[str, int | float | None]] | tuple[str, ...] | None - 推荐改用
Union并分行书写:Union[ list[dict[str, Union[int, float, None]]], tuple[str, ...], None ] - 团队统一风格非常重要:混合
Optional[str]和str | None会导致 mypy 报inconsistent-union
| 只存在于合法性中 AST 在分析阶段,它不参与操作时的逻辑;一旦用作普通表达式(如赋值、传参、反射),就会触发操作中的错误——这不是配置问题,而是语言设计本身决定的。