xChar
·a day ago

此文由 Mix Space 同步更新至 xLog
为获得最佳浏览体验,建议访问原始链接
https://do1e.cn/posts/citelab/how-to-use-uv


前言

大家都在宣传 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
  1. .git.gitignoreREADME.md 就不用解释了
  2. main.py 是一个示例 Python 文件,不需要可以直接删了
  3. pyproject.toml 是 Python 项目的配置文件里面记录了项目的元数据和依赖等信息,内容大致如下:
    [project]
    name = "test-project"
    version = "0.1.0"
    description = "Add your description here"
    readme = "README.md"
    requires-python = ">=3.12"
    dependencies = []
    
  4. .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]

:::warning
尽可能严格使用 uv 命令管理环境,虽然也提供了 uv pip 命令来兼容 pip 的用法,但该命令不会更新 pyproject.tomluv.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 版本的 torchtorchvision,而是安装 CPU 版本。

这里首先定义了一个名为 pytorch-cu130 的索引源,url 指定为上述 torch 文档中给出的 --index-url,不过更推荐使用南大镜像源的 https://mirror.nju.edu.cn/pytorch/whl/cu130
然后在 tool.uv.sources 中指定了 torchtorchvision 这两个包需要从该索引源安装(注:marker 指定了仅当操作系统是 Linux 或 Windows 时,才使用 pytorch-cu130 索引。对于其他操作系统,如 macOS,此配置会被忽略,依然使用默认源)。

复现环境

当你需要在另一台机器上复现当前项目的 Python 环境时,只需克隆项目代码后,运行以下命令:

uv sync

如果想要实现在另一个项目中复现相同的环境,则可以复制 pyproject.tomluv.lock.python-version 文件到目标项目目录下,更新 pyproject.toml 中的项目信息,然后运行同样的命令:

uv sync

构建和发布包

如果你是在写一个可供其他人安装的 Pypi 包,你还需要考虑哪些依赖是开发时依赖,哪些是运行时依赖,开发依赖需要使用 uv add --dev [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 = "[email protected]" }]
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

其他实用命令

  1. uv cache clear:清除 uv 缓存,释放其占用的磁盘空间
  2. uv tree:查看当前项目的依赖树
  3. uv run main.py:等价于激活虚拟环境后运行 python main.py,可以用来运行项目中的 Python 脚本
  4. uvx [script-name]:运行工具,有些 Python 包会提供命令行工具,可以使用 uvx 命令运行它们,例如 uvx NJUlogin -h
Loading comments...