使用 uv 锁定依赖版本的核心做法是运行 uv sync --frozen。该命令会读取项目根目录下的 uv.lock 文件,并严格按照文件中记录的哈希值和精确版本号安装所有依赖,忽略 pyproject.toml 中定义的宽松范围约束。这样做能确保构建环境与其他开发者或 ci/cd 流水线中的环境完全一致,避免因上游包更新导致的不可复现问题。

如何生成初始的锁定文件
在首次初始化项目时,需要让 uv 解析依赖树并生成 uv.lock。此时应使用 uv sync 命令(不带 --frozen 标志),它会检查 pyproject.toml 中的依赖声明,计算满足条件的最兼容版本,并将结果写入锁定文件。

mkdir my-project cd my-project uv init --no-readme uv add requests uv sync
上述操作完成后,当前目录下会生成 uv.lock。该文件包含了 requests 及其所有传递依赖(如 urllib3、certifi)的精确版本号和哈希值。后续任何人在该项目中执行 uv sync 都会复用这个锁定状态,除非显式要求更新。
立即学习“Python免费学习笔记(深入)”;
如何在团队中保持依赖一致性
当团队成员拉取代码后,必须确保他们安装的依赖与提交时的锁定文件一致。此时应强制使用 uv sync --frozen。如果本地缓存的包元数据与 uv.lock 中记录的不匹配,或者网络无法访问 PyPI,该命令会直接报错退出,从而防止静默下载错误版本的包。

# 团队成员拉取代码后 uv sync --frozen # 若需更新依赖,必须先修改 pyproject.toml 并重新生成锁定文件 uv add new-package uv sync # 这会更新 uv.lock git commit -am "Update dependencies"
通过这种工作流,uv.lock 成为唯一的真理来源。开发阶段可以使用 uv sync 来自动解决依赖冲突,但一旦代码准备就绪或部署到生产环境,就必须切换回 --frozen 模式以锁定状态。这种方式比传统的 pip freeze > requirements.txt 更可靠,因为 uv.lock 记录了完整的解析图,而不仅仅是最终安装的包列表。
基于 uv.lock 文件的具体内容结构
uv.lock 是一个 TOML 格式的文件,其核心结构由 package 数组和 resolution 规则组成。每个 package 条目都包含 name、version、source 以及用于验证完整性的 hashes 字段。例如,一个典型的包条目如下所示:
[[package]]
name = "requests"
version = "2.31.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "charset-normalizer" },
{ name = "idna" },
{ name = "urllib3" },
]
hashes = { sha256 = "58cd..." }这种结构确保了即使 PyPI 上的包被篡改或版本回滚,uv 也能通过校验 hashes 发现异常。同时,dependencies 数组列出了该包直接依赖的其他包名,结合全局的 resolution 部分,uv 能够重建出整个依赖树的拓扑关系。这种细粒度的锁定机制是 uv 实现快速且确定性安装的基础。


















