Mypy 入门指南:Python 静态类型检查

Mypy 是 Python 的静态类型检查器:在不运行代码的情况下发现类型错误。本文讲解安装配置、高级类型注解、类型守卫与收窄、泛型及类型覆盖率检查。

最佳实践
并发任务的多路径协同插画

直接回答:Mypy 分析你代码中的类型注解,在运行前揪出类型不匹配的错误——传错参数、返回值误用、None 访问属性这类经典崩溃在 CI 阶段就被拦截。 项目越大,静态检查的回报越高。

安装上手

pip install mypy
# greeting.py
def greet(name: str) -> str:
    return "你好, " + name

greet(42)        # 类型错误
greet("世界")     # 正确
mypy greeting.py
# error: Argument 1 to "greet" has incompatible type "int"; expected "str"

代码一行没跑,错误已被抓现行。

配置

pyproject.toml 中集中管理:

[tool.mypy]
python_version = "3.13"
strict = true                  # 最严格模式(新项目推荐)
warn_unused_ignores = true
exclude = ["tests/fixtures/"]

存量项目别直接开 strict——从基础配置起步,按模块逐步收紧(per-module 覆盖),否则一次几千条报错会直接劝退全组。

高级类型注解

from typing import Optional, Union, Literal, TypedDict

def find_user(uid: int) -> Optional[dict]: ...          # 可能返回 None
def parse(data: Union[str, bytes]) -> str: ...           # 多类型
def set_level(level: Literal["debug", "info"]) -> None: ...  # 枚举值

class UserDict(TypedDict):                               # 结构化字典
    name: str
    age: int

Python 3.10+ 支持 str | None,Python 3.12+ 支持 type X = ... 别名语法。

类型守卫与收窄

Mypy 理解控制流,会随判断收窄类型:

def process(value: str | None) -> str:
    if value is None:
        return "默认值"
    return value.upper()    # 此处 Mypy 已知 value 是 str

from typing import TypeGuard

def is_str_list(val: list[object]) -> TypeGuard[list[str]]:
    return all(isinstance(x, str) for x in val)

isinstance 检查、TypeGuard、assert 都是合法的收窄手段——让"我知道这里不是 None"变成机器可验证的事实。

泛型

from typing import TypeVar

T = TypeVar("T")

def first(items: list[T]) -> T:
    return items[0]

first([1, 2]).bit_length()   # Mypy 知道返回 int
first(["a"]).upper()         # 这里知道是 str

泛型让容器类函数既不丢类型又不重复写——写库代码必备。

类型覆盖率

pip install 'mypy[reports]'
mypy --html-report typecov src/

生成逐行的类型覆盖报告:哪些函数已注解、哪些还是 Any 裸奔。团队可以定"覆盖率只升不降"的 CI 门禁,类型化程度螺旋上升。

常见问题(FAQ)

Q:Mypy 会拖慢开发吗?
A:初期注解有成本,但换来的是重构自由(改签名全项目报错即改)与 IDE 补全质变。绝大多数团队过了适应期就离不开。

Q:第三方库没类型存根怎么办?
A:先找 库自带类型或 typeshed 维护的 types-* 存根包(不一定由原库作者发布);没有再 # type: ignore 或 Any 兜底。Mypy 允许灰度存在,不必一步到位。

Q:Mypy 和 Pyright/Pyrefly 怎么选?
A:Python 类型规范是共同依据,不以某一检查器结果定义规范。Mypy、Pyright 和 Pyrefly 在推断及插件上有差异,应按项目依赖评估,并统一 CI 与编辑器的检查目标。

官方参考

本文基于官方文档整理,未进行运行时或性能测试。示例中的业务函数、数据模型和部署地址需结合项目补全;局部片段不等同于完整生产应用。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台