使用 uv 管理 Python 环境
前言
大家都在宣传 uv 的快(UV:Python 包管理神器 - 比 pip 快 100 倍),不过针对我们实验室可能需要在多个机器之间迁移 Python 环境的情况,uv 复现环境的便利性同样也值得关注。
虽然已经在尽力向同门们推荐使用 uv,但大家对 conda 的依赖还是很深,也不愿意尝试新的工具。
因此还是决定写一篇教程,介绍一下 uv 的使用方法,稍微推动一下实验室环境管理的变革好了。
安装 uv
Windows 上我还是更推荐使用 winget 安装:
winget install astral.uv
Linux/macOS 上则可以参考官方文档使用 curl/wget 安装:
curl -LsSf https://astral.sh/uv/install.sh | sh
# 或者
wget -qO- https://astral.sh/uv/install.sh | sh
初始化 uv 环境
如果如果需要初始化一个新项目,可以在你的 workspace 目录下运行:
uv init [project-name]
cd [project-name]
或者需要将已有的 Python 项目迁移到 uv 环境下,可以在项目目录下运行:
cd [project-name]
uv init
此时项目目录中会新建下述文件:
.git
.gitignore
main.py
pyproject.toml
.python-version
README.md
.git、.gitignore、README.md就不用解释了main.py是一个示例 Python 文件,不需要可以直接删了pyproject.toml是 Python 项目的配置文件里面记录了项目的元数据和依赖等信息,内容大致如下:toml [project] name = "test-project" version = "0.1.0" description = "Add your description here" readme = "README.md" requires-python = ">=3.12" dependencies = [].python-version用于指定当前项目的 Python 版本
指定 Python 版本
编辑 pyproject.toml 文件中的 requires-python 字段,指定当前项目所需的 Python 版本,例如:==3.12、>=3.12 等。
然后运行以下命令安装指定版本的 Python:
uv python pin 3.12
创建虚拟环境
uv venv
此命令会在当前项目目录下创建一个虚拟环境,文件夹为 .venv,之后可以参考其输出信息激活虚拟环境,如:
source .venv/bin/activate
# 或者在 Windows 上
.venv\Scripts\activate
管理项目依赖
基本用法
需要安装新的依赖时,可以使用以下命令:
uv add [package-name]
实际上就是将之前 pip install 替换为 uv add 即可,但该命令除了将依赖安装到虚拟环境中,还会自动将依赖信息写入 pyproject.toml 文件中的 dependencies 字段,并且更新 uv.lock 锁文件以确保依赖版本的可复现性。uv.lock 文件不需要手动编辑,但是对环境复现相当重要,不要把它放进 .gitignore 中。
比如说安装 requests 后,pyproject.toml 中只会多一条 requests 依赖,而 uv.lock 中则会详细记录 requests 及其所有子依赖的具体版本信息,使用 uv tree 命令可以查看依赖树:
> uv tree
Resolved 6 packages in 0.75ms
test-project v0.1.0
└── requests v2.32.5
├── certifi v2025.11.12
├── charset-normalizer v3.4.4
├── idna v3.11
└── urllib3 v2.6.1
如果不需要某个依赖了,可以使用以下命令将其卸载:
uv remove [package-name]
uv pip 命令来兼容 pip 的用法,但该命令不会更新 pyproject.toml 和 uv.lock 文件,将导致环境不可复现的问题。镜像源
如果需要换 Pypi 镜像源,可在 pyproject.toml 文件中添加如下内容(以南大镜像源为例):
[[tool.uv.index]]
name = "nju-mirror"
url = "https://mirror.nju.edu.cn/pypi/web/simple"
default = true
pip 中的 index-url
部分包会在自己的 PyPI 镜像源上发布,比如 torch 的 pip 安装命令(参见 torch 官方文档)如下:
pip3 install torch torchvision --index-url https://download.pytorch.org/whl/cu130
需要参考 Using uv with PyTorch 将下述内容加入 pyproject.toml 文件中:
[[tool.uv.index]]
name = "pytorch-cu130"
url = "https://download.pytorch.org/whl/cu130"
explicit = true
[tool.uv.sources]
torch = [
{ index = "pytorch-cu130", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
]
torchvision = [
{ index = "pytorch-cu130", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
]
否则将不会安装 CUDA 版本的 torch 和 torchvision,而是安装 CPU 版本。
这里首先定义了一个名为 pytorch-cu130 的索引源,url 指定为上述 torch 文档中给出的 --index-url,不过更推荐使用南大镜像源的 https://mirror.nju.edu.cn/pytorch/whl/cu130。
然后在 tool.uv.sources 中指定了 torch 和 torchvision 这两个包需要从该索引源安装(注:marker 指定了仅当操作系统是 Linux 或 Windows 时,才使用 pytorch-cu130 索引。对于其他操作系统,如 macOS,此配置会被忽略,依然使用默认源)。
复现环境
当你需要在另一台机器上复现当前项目的 Python 环境时,只需克隆项目代码后,运行以下命令:
uv sync
如果想要实现在另一个项目中复现相同的环境,则可以复制 pyproject.toml、uv.lock、.python-version 文件到目标项目目录下,更新 pyproject.toml 中的项目信息,然后运行同样的命令:
uv sync
构建和发布包
如果你是在写一个可供其他人安装的 Pypi 包,你还需要考虑哪些依赖是开发时依赖,哪些是运行时依赖,开发依赖需要使用 uv add -D [package-name] 命令安装。
之后还需要补充 pyproject.toml 文件中的项目信息,比如作者、许可证,以及构建信息等,考虑到搞科研的大部分时候并不会发布包,这里就不展开讲了,可以参考下述内容进行理解:
[project]
name = "NJUlogin"
version = "3.6.1"
description = "The Nanjing University login module, which can be used to login to the various campus web sites"
authors = [{ name = "Do1e", email = "i@do1e.cn" }]
readme = "README.md"
requires-python = ">=3.10,<4.0"
dependencies = [
"requests>=2.32.0",
"pillow>=11.0.0",
"numpy>=2.0.0",
"lxml>=5.3.0",
"pycryptodome>=3.21.0",
"onnxruntime>=1.20.0",
"cryptography>=43.0.0",
]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
[project.scripts]
NJUlogin = "NJUlogin.__main__:main"
[tool.setuptools.packages.find]
include = ["NJUlogin", "NJUlogin.*"]
[project.urls]
Homepage = "https://github.com/Do1e/NJUlogin"
Repository = "https://github.com/Do1e/NJUlogin"
[dependency-groups]
dev = [
"pre-commit>=4.3.0",
"ruff>=0.14.6",
]
[[tool.uv.index]]
url = "https://mirror.nju.edu.cn/pypi/web/simple"
publish-url = "https://upload.pypi.org/legacy/"
default = true
[tool.ruff]
line-length = 100
[tool.ruff.lint]
ignore = ["C901", "E501", "E721", "E741", "F402", "F823"]
select = ["C", "E", "F", "I", "W"]
[tool.ruff.lint.isort]
lines-after-imports = 2
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"
[tool.uv]
package = true
之后即可,使用以下命令构建和发布包:
uv build
uv publish
其他实用命令
uv cache clear:清除 uv 缓存,释放其占用的磁盘空间uv tree:查看当前项目的依赖树uv run main.py:等价于激活虚拟环境后运行python main.py,可以用来运行项目中的 Python 脚本uvx [script-name]:运行工具,有些 Python 包会提供命令行工具,可以使用uvx命令运行它们,例如uvx NJUlogin -h。