Python 类型检查 Mypy 详解Mypy 是 Python 的静态类型检查器通过在运行前分析代码类型注解捕获潜在的类型错误让 Python 代码享受静态类型语言的安全性。一、安装与基本使用------------------# 安装 Mypy# pip install mypy# 验证安装版本mypy --version# 检查单个文件mypy app.py# 检查整个包mypy src/# 严格模式检查推荐新项目使用mypy --strict src/二、Mypy 配置文件------------------# 在 pyproject.toml 中配置 Mypy[tool.mypy]# Python 版本设定python_version 3.11# 严格模式等价于启用以下所有选项strict true# 要求所有函数都有类型注解disallow_untyped_defs true# 禁止未类型化的装饰器disallow_untyped_decorators true# 对 None 值的检查更严格strict_equality true# 检查未使用的忽略注释warn_unused_ignores true# 检查返回值类型与注解不匹配warn_return_any true# 禁止隐式 Optional如 x None 不标注 Optionalno_implicit_optional true# 允许重载装饰器allow_redefinition false# 需要导入的模块也要类型检查follow_imports normal# 排除不需要检查的文件exclude [build/,tests/,migrations/,]# 也可以使用 mypy.ini 配置文件[mypy]strict Truedisallow_untyped_defs True三、overload 装饰器---------------------# overload 用于为同一个函数声明多个类型签名from typing import overload, Union# overload 声明输入 int 返回 intoverloaddef double(value: int) - int: ...# overload 声明输入 str 返回 stroverloaddef double(value: str) - str: ...# 实际的实现函数不带类型装饰器def double(value):# 根据输入类型返回不同类型if isinstance(value, int):return value * 2elif isinstance(value, str):return value valueraise TypeError(不支持的类型)# mypy 会检查调用是否匹配重载签名result_int double(5) # mypy 推断类型为 intresult_str double(abc) # mypy 推断类型为 str四、类型存根文件Type Stubs-------------------------------# 类型存根是 .pyi 文件为无类型注解的库提供类型信息# 安装第三方库的类型存根# pip install types-requests# pip install types-PyYAML# pip install types-setuptools# 自动生成存根文件# mypy --generate-stubs mymodule# 使用 stub 包检测缺失的存根mypy --install-types# 手动编写存根文件example.pyi# example.pyi 文件内容def process_data(name: str, count: int 0) - list[str]: ...class DataHandler:def __init__(self, source: str) - None: ...def fetch(self, query: str) - dict[str, any]: ...五、reveal_type 调试---------------------# reveal_type 是 mypy 的特殊函数用于调试类型推断from typing import reveal_typex hello world# 在 mypy 运行时会输出Revealed type is strreveal_type(x)y [1, 2, 3]# 在 mypy 运行时会输出Revealed type is list[int]reveal_type(y)z {name: 张三, age: 30}# 在 mypy 运行时会输出Revealed type is dict[str, str | int]reveal_type(z)# reveal_type 仅在 mypy 检查时生效运行时无任何效果# 相当于注释不产生运行时开销六、类型忽略注释-----------------# 当 mypy 误报或需要绕过类型检查时使用忽略注释from typing import Any# 忽略特定行的类型错误value: Any some_external_function() # type: ignore# 指定忽略的错误码x unsafe_function() # type: ignore[assignment]# 对整个文件级别的忽略# mypy: ignore-errors# 在 pyproject.toml 中忽略特定模块的错误[[tool.mypy.overrides]]module legacy_module.*ignore_errors true七、高级类型特性----------------from typing import TypedDict, Literal, Protocol# TypedDict —— 字典的结构化类型class UserDict(TypedDict):# 定义字典的键值类型name: strage: intemail: struser: UserDict {name: 李四, age: 28, email: liexample.com}# Literal —— 限定字面量值def set_mode(mode: Literal[dev, prod, test]) - None:# mode 只能是 dev prod test 之一print(f模式设置为: {mode})# Protocol —— 结构子类型鸭子类型class Drawable(Protocol):# 定义协议任何有 draw 方法的类型def draw(self) - None: ...def render(obj: Drawable) - None:# 不需要继承只需有 draw 方法obj.draw()八、与项目集成--------------# 在 pre-commit 中配置 mypyrepos:- repo: https://github.com/pre-commit/mirrors-mypyrev: v1.7.0hooks:- id: mypyargs: [--strict, --ignore-missing-imports]additional_dependencies: [types-requests]# 在 CI 中运行 mypymypy src/ --strict --warn-unused-configs# 检查并生成报告mypy src/ --html-report mypy_report# 生成 HTML 格式的类型覆盖报告# Mypy 将 Python 的动态灵活性与静态类型的严谨性结合# 在大型项目中显著降低运行时类型错误的发生率。
Python类型检查Mypy
Python 类型检查 Mypy 详解Mypy 是 Python 的静态类型检查器通过在运行前分析代码类型注解捕获潜在的类型错误让 Python 代码享受静态类型语言的安全性。一、安装与基本使用------------------# 安装 Mypy# pip install mypy# 验证安装版本mypy --version# 检查单个文件mypy app.py# 检查整个包mypy src/# 严格模式检查推荐新项目使用mypy --strict src/二、Mypy 配置文件------------------# 在 pyproject.toml 中配置 Mypy[tool.mypy]# Python 版本设定python_version 3.11# 严格模式等价于启用以下所有选项strict true# 要求所有函数都有类型注解disallow_untyped_defs true# 禁止未类型化的装饰器disallow_untyped_decorators true# 对 None 值的检查更严格strict_equality true# 检查未使用的忽略注释warn_unused_ignores true# 检查返回值类型与注解不匹配warn_return_any true# 禁止隐式 Optional如 x None 不标注 Optionalno_implicit_optional true# 允许重载装饰器allow_redefinition false# 需要导入的模块也要类型检查follow_imports normal# 排除不需要检查的文件exclude [build/,tests/,migrations/,]# 也可以使用 mypy.ini 配置文件[mypy]strict Truedisallow_untyped_defs True三、overload 装饰器---------------------# overload 用于为同一个函数声明多个类型签名from typing import overload, Union# overload 声明输入 int 返回 intoverloaddef double(value: int) - int: ...# overload 声明输入 str 返回 stroverloaddef double(value: str) - str: ...# 实际的实现函数不带类型装饰器def double(value):# 根据输入类型返回不同类型if isinstance(value, int):return value * 2elif isinstance(value, str):return value valueraise TypeError(不支持的类型)# mypy 会检查调用是否匹配重载签名result_int double(5) # mypy 推断类型为 intresult_str double(abc) # mypy 推断类型为 str四、类型存根文件Type Stubs-------------------------------# 类型存根是 .pyi 文件为无类型注解的库提供类型信息# 安装第三方库的类型存根# pip install types-requests# pip install types-PyYAML# pip install types-setuptools# 自动生成存根文件# mypy --generate-stubs mymodule# 使用 stub 包检测缺失的存根mypy --install-types# 手动编写存根文件example.pyi# example.pyi 文件内容def process_data(name: str, count: int 0) - list[str]: ...class DataHandler:def __init__(self, source: str) - None: ...def fetch(self, query: str) - dict[str, any]: ...五、reveal_type 调试---------------------# reveal_type 是 mypy 的特殊函数用于调试类型推断from typing import reveal_typex hello world# 在 mypy 运行时会输出Revealed type is strreveal_type(x)y [1, 2, 3]# 在 mypy 运行时会输出Revealed type is list[int]reveal_type(y)z {name: 张三, age: 30}# 在 mypy 运行时会输出Revealed type is dict[str, str | int]reveal_type(z)# reveal_type 仅在 mypy 检查时生效运行时无任何效果# 相当于注释不产生运行时开销六、类型忽略注释-----------------# 当 mypy 误报或需要绕过类型检查时使用忽略注释from typing import Any# 忽略特定行的类型错误value: Any some_external_function() # type: ignore# 指定忽略的错误码x unsafe_function() # type: ignore[assignment]# 对整个文件级别的忽略# mypy: ignore-errors# 在 pyproject.toml 中忽略特定模块的错误[[tool.mypy.overrides]]module legacy_module.*ignore_errors true七、高级类型特性----------------from typing import TypedDict, Literal, Protocol# TypedDict —— 字典的结构化类型class UserDict(TypedDict):# 定义字典的键值类型name: strage: intemail: struser: UserDict {name: 李四, age: 28, email: liexample.com}# Literal —— 限定字面量值def set_mode(mode: Literal[dev, prod, test]) - None:# mode 只能是 dev prod test 之一print(f模式设置为: {mode})# Protocol —— 结构子类型鸭子类型class Drawable(Protocol):# 定义协议任何有 draw 方法的类型def draw(self) - None: ...def render(obj: Drawable) - None:# 不需要继承只需有 draw 方法obj.draw()八、与项目集成--------------# 在 pre-commit 中配置 mypyrepos:- repo: https://github.com/pre-commit/mirrors-mypyrev: v1.7.0hooks:- id: mypyargs: [--strict, --ignore-missing-imports]additional_dependencies: [types-requests]# 在 CI 中运行 mypymypy src/ --strict --warn-unused-configs# 检查并生成报告mypy src/ --html-report mypy_report# 生成 HTML 格式的类型覆盖报告# Mypy 将 Python 的动态灵活性与静态类型的严谨性结合# 在大型项目中显著降低运行时类型错误的发生率。