python 3.10+中优先在类型注解(如参数、返回值)用|,因其简洁且符合pep 604;需元编程(如get_origin/get_args)或兼容旧工具(mypy

Python 3.10 的 Union 写法和 | 操作符怎么选
Python 3.10 开始支持用 | 作为类型联合运算符(如 int | str),它等价于 Union[int, str],但不是所有地方都能直接替换。
常见错误是把 | 用在旧版类型检查器或运行时反射场景里:比如 get_origin(int | str) 在某些版本的 typing 工具中会返回 None,而 get_origin(Union[int, str]) 才稳定返回 Union。Pydantic v1 和部分静态检查工具(如 mypy 0.9x 之前)也不完全支持 |。
- 函数参数/返回值注解优先用
|,简洁且符合 PEP 604 - 需要调用
typing.get_origin()或get_args()做类型元编程时,改用Union - 若项目需兼容 Python Union,并从
typing导入(而非types.UnionType)
带泛型的类型注解如何配合 assert isinstance()
类型注解本身不参与运行时检查,isinstance(x, list[str]) 在 Python 3.10+ 会报 TypeError: isinstance() argument 2 cannot be a parameterized generic —— 因为 list[str] 是“参数化泛型”,不能直接当类传给 isinstance。
正确做法是剥离泛型参数,只对容器类型做基础检查,再手动验证元素:
from typing import List <p>def process(items: List[str]) -> None: assert isinstance(items, list), "items must be a list" assert all(isinstance(s, str) for s in items), "all items must be strings" </p>
-
isinstance(x, list)可行,isinstance(x, list[str])不可行 -
typing.get_origin(List[str]) is list可用于判断原始容器类型 - 测试中若需强校验,推荐用
pydantic.BaseModel或typeguard.check_type()替代手写断言
pytest 中验证类型注解是否被正确使用
类型注解不会自动触发运行时行为,所以仅靠 pytest 断言无法“测类型”。真正能测的是:函数是否按注解预期接收/返回值,以及类型检查器(如 mypy)是否报错。
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
实操建议分两层:
- 单元测试里用
assert覆盖边界输入(如传None进str参数),验证逻辑是否防御性处理,而非依赖类型系统 - CI 中加
mypy your_module.py,并配置--disallow-untyped-defs等严格选项 - 避免在测试里写
assert get_type_hints(func)['return'] == str—— 这只能读注解字符串,无法验证语义正确性
Literal 和 TypedDict 在测试断言中的实际用法
这两个类型在测试中特别有用:它们让字符串、字典结构变成可校验的契约。
例如定义接口返回格式:
from typing import Literal, TypedDict
<p>class UserResp(TypedDict):
status: Literal["ok", "error"]
code: int</p><p>def fetch_user() -> UserResp: ...</p><h1>测试中可直接断言字段存在性和字面值</h1><p>resp = fetch_user()
assert resp["status"] in ("ok", "error") # Literal 本质还是枚举式约束
assert isinstance(resp["code"], int)
</p>
-
Literal["a", "b"]在运行时就是"a"或"b",断言时直接比字符串即可 -
TypedDict不是运行时类型,isinstance(resp, UserResp)会报错;只能逐字段验证 - 若需运行时结构校验,用
pydantic.TypeAdapter(UserResp).validate_python(resp)
类型注解和断言是两套机制:前者面向工具链与协作契约,后者面向运行时逻辑保障。混用时最容易忽略的是——注解里的泛型信息在运行时基本不可用,别试图用 isinstance 直接验证 dict[str, int] 这类表达式。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










