Skip to content

UV:Rust重写的快速Python包管理器

约 2499 字大约 8 分钟

PythonRustShell

2025-07-17

前段时间,无意中了解到一个名为 UV 的 Rust 重写的快速包管理器,感觉非常有趣,为什么不用pip呢,各种包管理器的区别和联系、优缺点在哪里?这段时间用下来,感觉非常不错,速度快、功能强大、使用简单,版本依赖管理尤其突出。

Windows用户使用管理员模式的powershell执行下面的命令安装即可,如果有报错问问GPT就可以了,多半是权限的问题。

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

其他方式和操作系统安装参考:https://docs.astral.sh/uv/getting-started/installation/#standalone-installer

简单尝试

Python管理

反正就 uv python+ 命令,一般是先list看哪些版本可以下,find看安装了什么版本,install安装,uninstall卸载,pin特定版本到项目。

安装最新版cpython

uv python install [版本号] --reinstall(可选,覆盖安装)

升级python版本

uv python upgrade

代理执行

前提是.py文件中导入的包为标准类库,例如 import osimport sys 等等

uv run <python文> [参数]

有特定依赖项使用以下命令:

uv run <python文> --with <依赖> [参数]

显式声明依赖

2023年10月,python官方发布了PEP 723,引入了声明式内敛元数据以及pyproject.toml文件来声明项目的依赖项。

初始化

uv init --script <python文> --python <python版>

声明脚本依赖,这里向 example.py 文件添加了 requestsrich 这两个依赖项,版本限制为小于3的版本。

uv add --script example.py 'requests<3' 'rich'

修改下载地址(包索引)

如果你想使用其他镜像源,可以通过以下命令修改包索引地址:

uv add --index "https://example.com/simple" --script example.py 'requests<3' 'rich'

会一并写入 pyproject.toml 文件中。

# [[tool.uv.index]]
# url = "https://example.com/simple"

到这里,我们就可以看出它的长处了,可以显示定义下载源,版本依赖,甚至可以指定脚本文件。

锁定脚本依赖

与项目不同,脚本依赖是指特定脚本所需的依赖项。可以通过以下命令锁定脚本依赖:

uv lock --script example.py

生成的结构如下

Example

test.py

test.py.lock

test.py
import site
import sys
import ultralytics
test.py.lock
version = 1
revision = 2
requires-python = ">=3.13"

使用不同python

uv run <python文> --python <python版> [参数]

UV工具

uvx

只有当在无关紧要的测试、扁平化项目中用这个比较合适,uvx 等价于下面的命令:这样做是为了预先测试检查兼容python包版本,你知道的,python的包管理就和重庆的天气一样糟糕(

uv tool run
$ uvx pycowsay nb

  --
< nb >
  --
   \   ^__^
    \  (oo)\_______
       (__)\       )\/\
           ||----w |
           ||     ||

这个用的比较少,暂时写到这里。链接:https://docs.astral.sh/uv/guides/tools/#running-tools

项目管理常用

uv init hello-world
cd hello-world

生成的目录结构如下:

hello-world

.gitignore

.python-version

README.md

main.py

pyproject.toml

.gitignore
# Python-generated files
__pycache__/
*.py[oc]
build/
dist/
wheels/
*.egg-info

# Virtual environments
.venv
.python-version
3.13
README.md
main.py
def main():
    print("Hello from hello-world!")


if __name__ == "__main__":
    main()
pyproject.toml
[project]
name = "hello-world"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = []

项目结构

.venv

Scripts

include## 包含的头文件

lib## 所有的包安装位置

...

python.exe## 当前版本python执行程序

pyvenv.cfg

.python-version

README.md

main.py

pyproject.toml

uv.lock

pyproject.toml

查看所有字段

pyproject.toml
[project]
name = "hello-world" ##项目名称
version = "0.1.0" ##项目版本
description = "Add your description here" ##项目描述
readme = "README.md" ##项目说明文件
requires-python = ">=3.13" ##需要的python版本
dependencies = [] ## 依赖项列表

现在我们来试试安装yolo的依赖项,PYPI的镜像站点下载最好把代理关了或者设置镜像。

install.sh
uv add ultralytics

20250719.png

非常快,10秒内完成几百兆的文件下载和索引!(不过网速足够可能才行)

变化如下:

pyproject.toml
[project]
name = "hello-world"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
    "matplotlib>=3.10.3", 
    "tqdm>=4.67.1", 
    "ultralytics>=8.3.168", 
]

.python-version

告诉项目使用的Python版本号,初始化后自带,也可自定义

.venv

项目的虚拟环境,即与系统其余部分隔离的 Python 环境。这是 uv 将安装项目依赖项的位置。

uv.lock重要

uv.lock 是一个跨平台的 lockfile,其中包含有关项目依赖项的确切信息,类似与npm中的package.lockpnpm.lock,由uv自动化控制和生成,不要修改它。它可以:

  • 声明项目的开发平台
  • 声明项目所需的Python版本
  • 声明包及其依赖的下载地址、文件哈希等

文件哈希

通过哈希校验算法确认包未被篡改,保障包的完整性和安全性。

这样做的好处是让不同平台的开发者在安装依赖时获得相同的结果,确保项目在不同环境中的一致性。(哇,安装包很头疼的好吗?)

坏处是若下载地址失效或包被删除,可能会导致安装失败,可以手动尝试修改下载地址

pyproject.toml

添加、移除依赖

add、remove

uv add requests
uv remove requests

# Specify a version constraint
uv add 'requests==2.31.0'

# Add a git dependency, 手动指定
uv add git+https://github.com/psf/requests

从requirements.txt中同步

在常见的pip管理的项目中,我们会用到 requiremts.txt 来管理项目,uv支持迁移

uv add -r requirements.txt -c constraints.txt

升级某个包

正常的流程是先锁定其他包的版本,再执行某个包的升级任务

uv lock --upgrade-package <package>

查询项目版本

同步依赖

一般而言,写好代码后为了运行起来,新增的依赖我们自然而然就把依赖装好了,比如 uv add。但是如果是团队协作中,其他人可能没有安装你新增的依赖(反之亦然),这时候就需要同步依赖了。

uv sync # 同步依赖到uv.lock和pyproject.toml
.venv\Scripts\activate ## windows
source .venv/bin/activate ## linux/macOS
flask run -p 3000
python example.py

激活环境后,无需再使用 uv 前缀,直接使用 python 命令即可运行脚本。

造轮子

uv build

默认在当前目录生成dist目录,里面包含了打包好的文件。

dist

.venv

Scripts

include

lib

python.exe

pyvenv.cfg

dist

hello_world-0.1.0-py3-none-any.whl// wheel包,也就是所谓的轮子

hello_world-0.1.0.tar.gz// 源码包

hello_world.egg-info// hutch包信息

dependency_links.txt

PKG-INFO

requires.txt

SOURCES.txt

top_level.txt

main.py

pyproject.toml

uv.lock

README.md

.python-version

.gitignore

LICENSE

发布包

升级项目版本号

uv version n.e.w

平级升级,uv划分的标准从大到小为:major, minor, patch, stable, alpha, beta, rc, post, and dev

# 从稳定版到预发布版
uv version --bump patch --bump [alpha/beta/rc/post/dev]

# 预发布版的内部升级
uv version --bump [alpha/beta/rc/post/dev]

# 预发布版到稳定版
uv version --bump stable

同步注意

执行 uv version 后会自动更新 pyproject.tomluv.lock 文件中的版本号。不升级请执行 --frozen 参数

迁移

pip2uv

我们都知道,pip使用requirements.txt来管理依赖。例如,写入当前项目的依赖使用:

环境隔离

考虑使用venv虚拟环境来隔离项目依赖,避免某个Python版本全局安装包的冲突(想哭了😭)。

python -m venv
source .venv/bin/activate
pip ...

其中一种管理依赖的方式是pip-compile编译规则集 requirements.in 文件

例如,requirements.in 文件内容如下:

requirements.in
fastapi
pydantic>2

表示 fastapi 无版本约束, pydantic 版本大于2.0.0。

执行下面的命令来生成 requirements.txt 文件:

pip-compile requirements.in -o requirements.txt
requirements.txt

这个等同于 uv pip compile ,也是 pip-tools中的 pip-compile 命令。


另外一种比较不常见的方式是使用 pip freeze 命令来生成当前环境的依赖列表。

pip freeze > requirements.txt
requirements.txt
annotated-types==0.7.0
anyio==4.8.0
fastapi==0.115.11
idna==3.10
pydantic==2.10.6
pydantic-core==2.27.2
sniffio==1.3.1
starlette==0.46.1
typing-extensions==4.12.2

豪了,有以上的思路,我们就可以:

  1. 划分各种依赖环境

    比如项目有 dev | prod | staging 等环境,我们可以将依赖分为不同的文件,例如 requirements-dev.inrequirements-prod.in 等。

  2. 编写这些文件中的特殊依赖

    写好后分别保存到 requirements-dev.inrequirements-prod.in 文件中。

  3. 使用 uv pip compile 命令编译每个环境的依赖

    uv pip compile requirements-dev.in -o requirements-dev.txt
    # 或者 pip-compile requirements-dev.in -o requirements-dev.txt
    uv pip compile requirements-prod.in -o requirements-prod.txt
  4. 安装依赖

    pip install -r requirements-dev.txt
    pip install -r requirements-prod.txt

上面讨论的同一个项目中不同开发环境的依赖管理。再扩展下,不同的操作系统也是一样的。

不过 uv 支持跨平台解析,非常方便,比如 tqdm

tqdm

两个平台的解析为

Linux
tqdm==4.67.1
    # via -r requirements.in

colorama: Windows平台下的tqdm需要colorama包来支持终端颜色输出

这样每个平台间是不兼容的,

如果使用 uv 的 universal 选项 ,则会声明colorama的平台:

uv pip compile --universal requirements.in
requirements.txt
colorama==0.4.6 ; sys_platform == 'win32' # 这里就声明了
    # via tqdm
tqdm==4.67.1
    # via -r requirements.in