如何用 pip-tools 一键锁定 Python 依赖pip-compile 与 pip-sync 完整上手指南【免费下载链接】pip-toolsA set of tools to keep your pinned Python dependencies fresh.项目地址: https://gitcode.com/gh_mirrors/pi/pip-tools想象一下周五下午你的项目在本机一切正常代码合并、上线一气呵成。周一早上部署环境却报出ModuleNotFoundError——同事随手pip install了一个新包或某个依赖悄悄升级了小版本应用就这样倒在了在我电脑上能跑。这种环境失控的烦恼正是pip-tools要帮你消除的它用pip-compile把宽松的依赖声明编译成精确锁定的版本清单再用pip-sync让环境与清单完全对齐让你的 Python 依赖既可控又保持新鲜。pip-tools 本质是两条命令行工具的组合全项目只有一个核心目标帮你把想用的依赖和实际装上的依赖之间的鸿沟填平。接下来我们从最痛的场景出发一步步把它用起来。痛点开场依赖版本失控问题都出在没锁定先看一个真实得不能再真实的例子。你的requirements.txt里写着django4.0半年后同事把 Django 从 4.0.3 升级到了 4.2某些 API 行为变了线上开始告警但没人知道是谁、什么时候、为什么升级的。更糟的是本机、测试机、生产机各自装了不同的小版本三套环境三个样。问题的根源只有一个我们只声明了依赖的下限却从未锁定它实际的值。pip-tools 的思路很直接——把声明和锁定分成两步pip-compile读取你写好的依赖声明可以不含版本号解析出完整依赖树输出一份每个包都带精确版本号的清单pip-sync读取这份清单把当前环境里多出来的包卸载、缺失的包装上、版本不对的包换掉最终与环境完全一致。一句话总结pip-compile负责写清楚装什么pip-sync负责保证装的就是它。三步完成安装五分钟就能跑起来安装 pip-tools 和装普通 Python 包没有区别唯一要注意的是它必须装在项目的虚拟环境里原因稍后揭晓。第一步激活虚拟环境$ source .venv/bin/activate (venv) $第二步安装(venv) $ python -m pip install pip-tools第三步验证一下看到版本号就说明装好了(venv) $ pip-compile --version装完你就多了两个命令pip-compile和pip-sync。如果你习惯用模块方式运行也可以写python -m piptools compile和python -m piptools sync效果完全相同。小提示如果你在多个 Python 版本间切换可以用python3.11 -m piptools compile这类写法显式指定解释器版本。五分钟跑通首个示例从 requirements.in 到锁定的 requirements.txt现在做第一个实验。新建一个文本文件requirements.in只写一行、不写版本号# requirements.in django运行编译命令(venv) $ pip-compile requirements.in几秒后目录里出现requirements.txt内容大致长这样具体版本取决于你当时的 Python 环境asgiref3.6.0 # via django django4.1.7 # via -r requirements.in sqlparse0.4.3 # via django注意看两件事你只声明了django但asgiref、sqlparse这些间接依赖也被自动解析并锁定了每行末尾的# via注释记录了依赖来源相当于一份溯源档案以后排查问题时能一眼看出谁引入了谁。这就是 pip-tools 的核心价值你只管声明要什么它替你算清楚该锁什么。核心工作流一次安装、一次配置、一次运行把上面的实验扩展成日常规范就是一套三步走的固定动作。一次配置在哪里声明依赖pip-compile 支持多种依赖声明来源你按项目习惯选一种即可requirements.in 文件最简单适合不想把项目打包成 Python 包的情况我们刚才已经用过了pyproject.toml新项目的标准做法pip-compile会读取[project.dependencies]和[project.optional-dependencies]setup.py / setup.cfg老项目用 setuptools 声明依赖也能被直接识别。举个例子一个用 Hatch 打包的 Django 应用可以这样写pyproject.toml[build-system] requires [hatchling] build-backend hatchling.build [project] name my-cool-django-app version 42 dependencies [django] [project.optional-dependencies] dev [pytest]一次运行编译 同步对着上面的pyproject.toml一条命令产出生产锁定文件(venv) $ pip-compile -o requirements.txt pyproject.toml想连开发依赖一起锁定加一个--extra参数(venv) $ pip-compile --extra dev -o dev-requirements.txt pyproject.toml于是你得到了两份互不干扰的清单requirements.txt管生产dev-requirements.txt管开发。锁定完成之后轮到pip-sync上场。它会按清单精确校准环境该装的装、该升级的升级、该卸载的卸载(venv) $ pip-sync Uninstalling flake8-2.4.1: Successfully uninstalled flake8-2.4.1 Collecting click4.1 ... Successfully installed click-4.1从此部署前跑一遍pip-sync就和提交前跑一遍测试一样自然。实战案例三个场景看懂它的用法与收益光看流程还不够我们放进三个真实的业务场景里感受一下。案例一上线前锁定生产依赖团队要做一次版本发布你先写好requirements.in声明所有顶层依赖然后执行pip-compile生成requirements.txt。把两个文件都提交到版本库.in是人类可读的意图.txt是机器执行的真相。之后任何人 clone 代码只要pip-sync就能复现出一模一样的环境生产部署不再依赖某台机器碰巧装过什么。收益是实打实的构建可预测、环境可复现。案例二生产与开发依赖分层管理一个 Django 项目生产上想用最新的 2.1 版本开发时还需要 debug 工具。你可以建两个.in文件# requirements.in django2.2# dev-requirements.in -c requirements.txt django-debug-toolbar2.2关键就在dev-requirements.in第一行的-c requirements.txt——它声明开发依赖必须受生产锁定文件约束。先编译生产文件再编译开发文件(venv) $ pip-compile (venv) $ pip-compile dev-requirements.in你会发现即使 Django 2.2 已经发布开发环境的 Django 仍被约束在 2.1 系列因为编译时参考了生产清单。最后在开发环境一次同步两份文件(venv) $ pip-sync requirements.txt dev-requirements.txt生产与开发既能各取所需又不会互相污染这才是分层依赖管理的正确姿势。案例三定期升级依赖而不是放任不管锁定不等于一劳永逸依赖也需要定期体检。pip-tools 提供了精确的升级控制# 只升级 django 到最新版 (venv) $ pip-compile --upgrade-package django # 同时升级多个并把 requests 固定到 2.0.0 (venv) $ pip-compile --upgrade-package django --upgrade-package requests2.0.0 # 一次性升级全部依赖 (venv) $ pip-compile --upgrade如果对安全性要求高还可以开启哈希校验模式(venv) $ pip-compile --generate-hashes requirements.in生成的文件里每个包都带--hashsha256:...安装时 pip 会逐包校验指纹杜绝依赖被篡改的风险CI 环境尤其受用。常见问题与避坑新手最容易踩的六个坑最后把高频坑一次性讲清楚帮你少走弯路。锁定之后pip-compile不会自动升级。只要现有requirements.txt满足声明即使有新版本它也不会动。想升级必须显式加--upgrade或--upgrade-package。这不是 bug而是稳定优先的设计。pip-sync不会碰 pip、setuptools 和 pip-tools 自己。它们属于打包工具需要升级时请手动执行python -m pip install --upgrade。一定要在虚拟环境里运行。pip-compile会按当前环境解析依赖的环境标记比如仅在 Windows 上安装这种条件pip-sync则靠当前环境识别已装包。装错环境结果就会不对。别手改requirements.txt。它是由.in或pyproject.toml生成的产物下次编译会被覆盖。想调整依赖改声明文件再重新编译。不同环境的编译结果可能不同。操作系统、Python 版本、解释器都会影响依赖解析跨平台项目最好在每个目标环境分别执行一次pip-compile。注意 Python 版本要求。pip-tools 需要 Python 3.9 及以上太老的解释器会直接安装失败。下一步把锁定变成日常习惯到这里你已经掌握了 pip-tools 最核心的用法声明依赖、编译锁定、同步环境、按需升级。把它纳入日常流程后你会发现依赖又出问题了这句话在团队里出现的频率直线下降。想更进一步项目自带的 docs 目录里还有不少进阶内容可以探索把pip-compile接进 pre-commit 钩子实现提交前自动校验、用[tool.pip-tools]配置块把常用参数写进pyproject.toml免去重复输入、用--resolver在回溯解析器与旧解析器之间切换……这些技巧能让你的依赖管理流程更自动化。从今天起把这两条命令记进小本本pip-compile管写清楚pip-sync管装得对。下次再有人抱怨环境不一致你已经有底气把这个问题彻底解决掉了。⚡【免费下载链接】pip-toolsA set of tools to keep your pinned Python dependencies fresh.项目地址: https://gitcode.com/gh_mirrors/pi/pip-tools创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考