type hints 是静态契约,非运行时强制;必须标注函数参数和返回值,优先用 |(python 3.10+),避免 any,类属性需 @dataclass 或 __annotations__,模块变量也须显式标注。

Type Hints 不是运行时强制约束,而是给开发者和工具(如 mypy、IDE)看的契约。用对了能显著减少类型相关 bug 和协作成本;用错了反而增加维护负担。
什么时候必须加 Type Hint:函数入参和返回值
这是最值得投入的地方——IDE 自动补全、mypy 静态检查、重构时参数变更提示都依赖它。不写这里,其他地方加得再全也收效甚微。
-
def parse_config(path: str) -> dict[str, Any]比def parse_config(path)更易理解、更安全 - 避免用
Any代替具体类型,除非真不确定(比如解析未知 JSON);优先用Union[str, int]或Optional[int] - 嵌套结构别硬写:
list[dict[str, Union[str, float]]]可读性差,应定义class ConfigItem(TypedDict): ...后直接用list[ConfigItem]
类属性和实例变量必须用 __annotations__ 或 dataclass
普通 class 中写 self.name = "xxx" 不会自动推导类型,IDE 和 mypy 都无法校验后续使用是否合法。
- 推荐用
@dataclass:@dataclass类中name: str会被正确识别为实例属性类型 - 非 dataclass 场景,用
__annotations__显式声明:class Cache:后加__annotations__ = {"items": list[str]}(注意不是赋值语句) - 别在
__init__里只靠赋值猜类型:self.items = []→ mypy 默认认为是list[Unknown],后续.append(42)不报错,但.append("abc")也不报错
typing.Union 和 |(Python 3.10+)混用会触发 mypy 报错
mypy 默认不启用 PEP 604 支持,如果代码里同时出现 Union[str, int] 和 str | int,可能因版本或配置不一致导致检查结果不稳定。
- 团队统一用一种风格:Python ≥ 3.10 项目建议全用
str | int,更简洁且是未来方向 - 若需兼容旧版或第三方库(如 Pydantic v1),保持
Union;但注意from typing import Union在 3.10+ 已被标记为 deprecated(仅警告,不报错) - mypy 配置中可加
[mypy]→python_version = "3.10"并启用enable_error_code = "pep604"来提前暴露混合写法问题
运行时类型检查(如 typeguard)不是 Type Hints 的替代品
Type Hints 是静态契约,typeguard 是动态校验,二者目标不同。过度依赖运行时检查会掩盖设计缺陷,还拖慢性能。
- 只在极少数场景加运行时校验:如接收外部不可信输入(API 请求体)、调试阶段快速定位类型误传
- 不要给每个函数加
@typechecked—— 它会拦截所有调用,包括内部高频方法,开销明显 - 真正需要强保障的接口,用 Pydantic model 替代裸 dict + typeguard,既校验又提供默认值、序列化等能力
最容易被忽略的是模块级变量和全局常量的类型标注。比如 DEFAULT_TIMEOUT = 30,不加 DEFAULT_TIMEOUT: int = 30,下游任何地方修改它为字符串都不会被 mypy 捕获——而这种错误往往到集成测试才暴露。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











