最近在重构一个老项目时,我决定把原来的 Pref="/tag/849/" style="color:#643D3D;font-weight:bold;">ipenv 换成纯 pyproject.toml 管理依赖。不是因为 Pipenv 不好,而是随着 Python 生态的发展,pyproject.toml 已经足够强大,能解决大部分实际问题,还不用额外学一套工具。
从 Pipfile 到 pyproject.toml
以前用 Pipenv,主要是图它自动维护 Pipfile 和 Pipfile.lock,开发依赖和生产依赖分得清楚。但时间一长,发现它启动慢、偶尔锁版本出问题,CI 里也容易卡住。而现在的构建系统,比如 Poetry 或 Hatch,甚至原生 pip,都直接支持 pyproject.toml,格式统一,社区也越来越认可。
比如一个典型的 pyproject.toml 配置:
[build-system]
requires = ["setuptools>=61", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "myapp"
version = "0.1.0"
dependencies = [
"requests>=2.25.0",
"click>=8.0.0",
]
[project.optional-dependencies]
develop = [
"pytest>=7.0.0",
"black",
"flake8"
]
[tool.setuptools.packages.find]
where = ["src"]
为什么现在更适合迁移
PyPA 推动的现代 Python 打包标准让 pyproject.toml 成了事实上的配置中心。你不再需要 Pipfile、requirements.txt、setup.py 一堆文件。一个文件搞定构建、依赖、元信息,连 IDE 都能直接读取。
而且 CI 脚本变得更简单。以前用 Pipenv 得先安装 pipenv,再 pipenv install,现在直接:
python -m pip install .
python -m pip install .[develop] # 安装开发依赖
本地开发也方便。团队新人 checkout 代码后,一句 pip install . 就能跑起来,不用额外装 Pipenv 或担心虚拟环境混乱。
迁移并不复杂
如果你还在用 Pipenv,迁移到 pyproject.toml 其实不难。先把 Pipfile 里的 dependencies 和 dev-dependencies 搬过来,选个合适的 build-backend,比如 setuptools 或 poetry-core,然后把脚本命令挪到 pyproject.toml 的 [tool] 里,或者交给 task runner 比如 just 或 make。
有次我在一个小团队项目中推动这个改动,原本大家担心兼容问题,结果试了一周,发现不仅部署更快,本地协作也没出现依赖冲突。反倒是省去了反复解释 Pipenv 各种奇怪行为的时间。
工具在进化,习惯也要变
Pipenv 曾经解决了 requirements.txt 手动维护的痛点,但现在 pyproject.toml 连配置结构都标准化了。就像从前用 virtualenv + pip,后来被 venv + pip 取代一样,工具总是在往前走。
如果你的新项目还在犹豫用什么管理依赖,不妨直接从 pyproject.toml 开始。少一个依赖,少一个潜在问题。