2026-05-25 ·
日常编程 ·
167552
Python 3.10起int | str是合法类型注解,等价于Union[int, str],但本质是PEP 604引入的底层变更:无需导入、生成UnionType实例、嵌套更简洁,且Union已弃用。
Python 3.10 起,int | str 就是合法的类型注解,它和 Union[int, str] 完全等价,但不需要导入、更短、更贴近自然语言逻辑——这不是语法糖,而是 PEP 604 正式引入的底层类型系统变更。
Union[int, str] 和 int | str 的实际差异在哪
表面上只是写法变短,但背后有三处关键区别:
Union 是一个泛型类,需要从 typing 模块导入;| 是运算符,直接作用于类型对象,无需任何导入
运行时行为不同:int | str 在 Python 3.10+ 中生成的是 types.UnionType 实例,而 Union[int, str] 生成的是 typing.Union 类型(在 3.10+ 中已被标记为弃用警告)
嵌套表达更清晰:比如 list[int | str] 比 list[Union[int, str]] 少两层括号,也避免和函数调用混淆
什么时候会触发 DeprecationWarning
如果你还在用 Union,且项目已升级到 Python 3.10+,静态检查工具(如 mypy)或运行时(启用 -W default)可能不会报错,但以下情况会明确提示:
显式使用 from typing import Union 后又没实际用到它(mypy 可能报 unused-import)
在类型别名中写 MyType = Union[int, str],而代码中其他地方都用 | —— 工具链可能认为风格不一致
某些 IDE(如 VS Code + Pylance)会在 hover 提示里标注 “Union is deprecated in favor of |”
Optional[str] 还能不能用 | 替代
可以,但不推荐直接写 str | None 来代替 Optional[str],原因很实际:
Python 3.14.3
微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。
Optional[T] 是 Union[T, None] 的别名,语义上强调“可选性”,而 T | None 更偏向“类型并集”——阅读者第一反应不同
大多数类型检查器对 Optional 有特殊处理(比如自动推导默认值为 None),T | None 有时会丢失这部分上下文
框架如 FastAPI、Pydantic 仍优先识别 Optional 作为字段可空标志,T | None 虽然也能工作,但文档生成或错误提示可能不够精准
真实项目里最容易忽略的兼容性坑
不是语法写错,而是环境和工具链没跟上:
旧版 mypy(int | str,会直接报 SyntaxError —— 升级 mypy 到 0.930+ 是硬要求
CI 流水线如果还跑在 Python 3.9 或更早版本,| 写法会直接让整个 type check 阶段失败,连语法解析都过不去
团队协作时,有人用 3.10+ 写了 dict[str, int | float],另一人用 3.9 打开就 SyntaxError —— 不是代码问题,是解释器版本卡死
真正要落地 | 写法,得先确认 Python 版本、mypy 版本、IDE 插件支持度这三者都对齐。否则,简洁性反而成了协作障碍。
ModuleNotFoundError本质是Python解释器在sys.path中未找到目标模块。需检查sys.path是否包含模块实际路径、pip与Python解释器是否匹配、虚拟环境是否激活,并优先用python -m pip安装确保环境一致。 ModuleNotFoundError 本质是 Python 找不到模块的路径问题 这个错误不是代码写错了,而是 Python 解释器在 sys.pa...
2026-05-28 · 日常编程 · 277321
NumPy 的 ndarray 子类在运行时能保持类型(如切片返回原 subclass 实例),但静态类型检查器(如 Pyright)因缺乏泛型返回类型推导而报错;需手动重写 __getitem__ 并使用 Self 或协变泛型确保类型安全。 numpy 的 `ndarray` 子类在运行时能保持类型(如切片返回原 subclass 实例),但静态类型检查器(如 pyright)因缺乏泛型返回类型...
2026-05-28 · 日常编程 · 113082
该错误源于张量类型不匹配:模型输入/输出需float32,分类标签需int64(torch.long);定位时用print(x.dtype)检查model(input)输出和target,注意torch.tensor()默认推断类型,预处理阶段应显式指定dtype。 PyTorch中RuntimeError: expected scalar type Float but found Long怎么快...
2026-05-27 · 日常编程 · 107637
必须重写JSONEncoder,因jsonify依赖json.dumps默认不支持Decimal;需继承flask.json.JSONEncoder并重写default方法,对Decimal转float后交由父类处理,再通过app.json_encoder全局注册。 直接结论:必须重写 JSONEncoder,不能靠 int() 或 float() 强转字段再传给 jsonify —— 那只是掩盖...
2026-05-27 · 日常编程 · 262200
本文介绍如何为接受任意JSON可序列化输入的函数设计精确、安全且符合mypy规范的类型提示,解决Union[List[Any], Dict[Any, Any]]不完整、禁用Any及递归类型声明等核心问题。 本文介绍如何为接受任意json可序列化输入的函数设计精确、安全且符合mypy规范的类型提示,解决`union[list[any], dict[any, any]]`不完整、禁用`any`及递归类...
2026-05-27 · 日常编程 · 54552
本文介绍如何为支持json.dumps的函数参数设计严谨、可静态检查的类型提示,解决Union[List[Any], Dict[Any, Any]]不完整且违反mypy规范的问题,推荐使用递归TypeAlias定义完整的JSON可序列化类型。 本文介绍如何为支持`json.dumps`的函数参数设计严谨、可静态检查的类型提示,解决`union[list[any], dict[any, any]]`...
2026-05-27 · 日常编程 · 61847
本文介绍如何为接受任意json可序列化输入的python函数编写精确、安全且mypy友好的类型注解,涵盖递归类型别名的定义、使用方式及注意事项。 本文介绍如何为接受任意json可序列化输入的python函数编写精确、安全且mypy友好的类型注解,涵盖递归类型别名的定义、使用方式及注意事项。 在Python中,json.dumps() 能处理的值类型并非无限宽泛,而是严格限定于以下几类:None、布...
2026-05-27 · 日常编程 · 174070
本文介绍如何为接受任意JSON可序列化对象的函数参数提供准确、安全且mypy友好的类型提示,通过递归TypeAlias精准覆盖json.dumps原生支持及自定义编码器扩展的全部合法输入类型。 本文介绍如何为接受任意json可序列化对象的函数参数提供准确、安全且mypy友好的类型提示,通过递归`typealias`精准覆盖`json.dumps`原生支持及自定义编码器扩展的全部合法输入类型。 在P...
数据泄露的根本原因是预处理步骤(如标准化、缺失值填充)在全部数据上拟合而非每折训练集独立拟合;正确做法是将预处理器与模型封装进Pipeline,并由cross_val_score在每折中单独fit。 Scikit-learn模型评估出现数据泄露,根本原因不是交叉验证本身有问题,而是预处理步骤(比如标准化、缺失值填充)被错误地应用在了整个数据集上,而不是严格限制在每次 CV 折的训练子集内。 cro...
2026-05-26 · 日常编程 · 189141
Python类型标注仅作注释,运行时无约束;mypy是独立静态检查工具,需手动安装、调用并配置(如--strict)才能生效,Any类型会绕过所有检查。 Python 运行时根本不管类型标注 类型标注(如 name: str、def func(x: int) -> bool:)在 Python 解释器眼里只是注释——它不会拦截、转换或拒绝错误类型的值。哪怕你写 greet(42) 而函数标注...
2026-05-26 · 日常编程 · 38634