Python 项目在团队协作中常常面临环境不一致、脚本分散难维护的问题。hatch 作为一个现代的项目管理与打包工具,把环境管理与脚本定义都收敛到了 pyproject.toml 文件中,让开发、测试、构建过程变得可声明、可复现。

hatch 的环境管理核心概念
hatch 的环境(environment)是一组相互隔离的依赖与配置集合。默认情况下,hatch 会为项目创建一个名为 default 的虚拟环境,但你可以根据用途定义多个环境,例如区分单元测试、类型检查、文档构建等场景。每个环境都可以指定不同的 dependencies、Python 版本以及额外的安装步骤。
与传统手动创建 venv 再 pip install 的方式不同,hatch 在运行命令时若发现环境不存在,会自动创建并安装对应依赖。这种懒加载机制减少了人工操作,也避免了忘记激活环境导致包装到全局的问题。环境目录默认放在项目外的统一缓存区,保持仓库干净。
在 pyproject.toml 中定义环境
下面是一段典型的环境配置,展示了如何声明两个独立环境:
[tool.hatch.envs.default] dependencies = [ "pytest", "requests" ] [tool.hatch.envs.docs] dependencies = [ "mkdocs", "mkdocs-material" ] [tool.hatch.envs.docs.scripts] build = "mkdocs build" serve = "mkdocs serve"
上述配置中,default 环境用于日常开发,docs 环境专门服务于文档生成。执行 hatch run docs:build 时,hatch 会确保 docs 环境存在并直接运行 mkdocs build,无需手动切换。
如果项目需要测试多个 Python 版本,可以使用矩阵(matrix)功能批量生成环境。例如下面的写法会自动为 3.9 到 3.11 创建对应的测试环境:
[tool.hatch.envs.test] dependencies = ["pytest"] [[tool.hatch.envs.test.matrix]] python = ["3.9", "3.10", "3.11"]
hatch 的脚本定义方式
hatch 允许在配置中直接定义脚本,分为命令型脚本与函数型脚本两类。命令型脚本适合包装 Shell 指令,函数型脚本则能在项目代码内复用 Python 逻辑。
命令型脚本
命令型脚本写在 environments 的 scripts 表下,值可以是字符串或字符串列表。列表形式会按顺序执行,且支持用 : 前缀调用其他脚本。
[tool.hatch.envs.default.scripts] lint = "flake8 src tests" fmt = "black src tests" check = [ "lint", "fmt --check", "pytest" ]
运行 hatch run check 会依次执行 lint、格式检查与测试。脚本也能接收外部参数,例如定义 run = "python -m myapp" 后,执行 hatch run run -- --port 8000 会把 --port 8000 透传给 Python 程序。
命令型脚本的优势是直观、零编码成本,但对复杂逻辑或跨平台路径处理不够灵活。Windows 与 Unix 的 Shell 差异可能导致同一脚本在不同系统行为不同,此时应考虑函数型脚本。
函数型脚本
函数型脚本指向项目内某个 Python 可调用对象,hatch 会在对应环境中导入并调用它。适合需要读写文件、解析配置或调用内部 API 的任务。
[tool.hatch.envs.default.scripts] greet = "my_package.cli:say_hello"
对应的 Python 代码可以这么写:
# my_package/cli.py
def say_hello():
print("Hello from hatch script")
函数型脚本同样支持参数,hatch 会把命令行剩余参数作为字符串列表传入函数的 args 参数(若签名声明了的话)。这让脚本既能享受配置化管理,又不失编程表达能力。
环境依赖与脚本的联动
hatch 的一个实用特性是脚本可以声明依赖前置。比如某个脚本需要先安装额外工具,可通过 environments 的 extra dependencies 控制,或者在脚本执行前调用安装命令。此外,利用 hatch run 的多环境调度,可以把测试、构建、发布串成流水线。
| 管理方式 | 传统方案 | hatch 方案 |
|---|---|---|
| 环境隔离 | 手动 venv + requirements.txt | 声明式 envs 配置 |
| 脚本维护 | Makefile / shell 脚本 | pyproject.toml scripts |
| 多版本测试 | tox 独立配置 | matrix 内置支持 |
从上表可以看出,hatch 把原本散落在多处的信息集中到了单一配置文件,降低了新成员的理解成本。当仓库被克隆后,只需执行 hatch shell 就能进入默认环境,无需查阅 README 里的长篇安装说明。
常见使用误区与建议
不少使用者会把所有依赖都堆在 default 环境,导致环境臃肿、安装缓慢。建议按用途拆分环境,例如测试依赖不进入生产环境,文档工具单独隔离。另一个误区是滥用函数型脚本处理简单命令,反而增加调试难度,简单调用优先用命令型脚本即可。
在 CI 场景中,推荐显式指定环境名运行,如 hatch run test:pytest,避免依赖默认环境变动引发非预期行为。结合 hatch 的构建后端,还能在打包阶段自动校验环境与脚本,进一步保障发布质量。