当前位置: 首页 > 图灵资讯 > 行业资讯> 为什么Python 3.10+推荐使用联合类型符号|替代Union?

为什么Python 3.10+推荐使用联合类型符号|替代Union?

来源:图灵python
时间: 2026-07-30 17:12:52
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 然后将函数传输到类型操作中,大概率触发 AttributeErrorTypeError
| 只在类型标注上下文中合法

它只在函数签名、变量注释、类属性等 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__ 属性
mypy/pyright 对 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 在分析阶段,它不参与操作时的逻辑;一旦用作普通表达式(如赋值、传参、反射),就会触发操作中的错误——这不是配置问题,而是语言设计本身决定的。