高效Python开发:uv包管理器全面解析
目录
- uv简介
- 亮点
- 与 pip、pip-tools、pipx、poetry、pyenv、virtualenv 对比
- 安装uv
- 快速开始
- uv安装python
- uv运行脚本
- 运行无依赖的脚本
- 运行有依赖的脚本
- 创建带元数据的 Python 脚本
- 使用 shebang 创建可执行文件
- 使用其他package indexes
- 锁定依赖
- 提高可复现性
- 指定不同的 Python 版本
- 运行 GUI 脚本
- uv运行工具
- 运行工具
- 包名与命令名不同的情况
- 指定版本运行工具
- 请求 extras(附加功能)
- 请求不同来源
- 使用插件的命令
- 安装工具
- Ruff:极速的Python代码检查工具
- 升级工具
- 指定 Python 版本
- uv项目管理
- 项目结构说明
- pyproject.toml
- .python-version
- .venv
- uv.lock
- 依赖管理
- 运行命令
- 构建发行包
- uv构建和发布包
- 构建你的包
- 发布你的包
- 安装测试
- 总结
uv简介
uv 是由 Astral 公司开发,用 Rust 编写的快速 Python 包管理器。
它最初作为 pip 工作流的替代品推出,如今已扩展成为一个端到端的解决方案,能够管理 Python 项目、命令行工具、单文件脚本,甚至 Python 本身。
uv 类似于 Python 版本的 Cargo,为开发者提供一个快速、可靠、易用的统一接口。
主要特性如下:
-
端到端项目管理
通过uv run
、uv lock
和uv sync
等命令,uv 可以基于标准元数据生成跨平台的锁文件并安装依赖。
相比 Poetry、PDM 和 Rye 等工具,uv 在性能上更具优势。 -
工具管理
使用uv tool install
和uv tool run
(别名uvx
),可以在隔离的虚拟环境中安装和运行命令行工具。
支持执行一次性命令,无需显式安装,速度比 pipx 更快。 -
Python 安装
通过uv python install
可以自动下载安装 Python,类似 pyenv,但效率更高。 -
单文件脚本支持
支持基于 PEP 723 的内联元数据,只需使用uv run
即可执行独立的 Python 脚本。
这些功能建立在 uv 高性能的跨平台依赖解析器之上。无论是处理小型脚本还是大型项目,uv 都能提供良好的性能和可靠性,适合从初学者到专家的各种 Python 开发需求。
亮点
官方文档:https://docs.astral.sh/uv/
- 🚀 一个工具替代 pip、pip-tools、pipx、poetry、pyenv、twine、virtualenv 等多个工具
- ⚡️ 比 pip 快 10 到 100 倍
- 🗂️ 提供全面的项目管理功能,支持通用锁文件
- ❇️ 支持运行脚本,并支持内联依赖元数据
- 🐍 可安装并管理多个 Python 版本
- 🛠️ 支持运行和安装以 Python 包发布的工具
- 🔩 提供兼容 pip 的接口,在保留熟悉 CLI 的同时获得性能提升
- 🏢 支持类 Cargo 的工作区,用于构建可扩展项目
- 💾 节省磁盘空间,依赖去重采用全局缓存
- ⏬ 可通过 curl 或 pip 安装,无需预装 Rust 或 Python
- 🖥️ 支持 macOS、Linux 和 Windows
- uv 由 Ruff 的开发者 Astral 团队支持
与 pip、pip-tools、pipx、poetry、pyenv、virtualenv 对比
📦 pip
简介:pip 是 Python 官方推荐的包管理器,由 Python Packaging Authority(PyPA)维护。(PyPI)
功能:
- 安装和卸载 Python 包
- 支持从 PyPI、Git 仓库、本地目录等多种来源安装(GitHub)
优点:
- 广泛使用,社区支持良好
- 简单易用,适合初学者(PyPI)
缺点:
- 不支持依赖锁定,可能导致环境不一致
- 缺乏虚拟环境和项目管理功能
适用场景:
- 快速安装单个包
- 与其他工具(如 virtualenv、pip-tools)结合使用(GitHub)
🔧 pip-tools
简介:pip-tools 是由 Jazzband 社区维护的工具集,旨在增强 pip 的功能。
功能:
pip-compile
:从requirements.in
生成锁定的requirements.txt
pip-sync
:根据requirements.txt
安装或卸载依赖(Poetry)
优点:
- 确保项目依赖的一致性
- 与 pip 兼容,易于集成
缺点:
- 依赖解析速度较慢
- 功能相对单一,仅处理依赖锁定
适用场景:
- 需要严格依赖锁定的项目
- 与 pip 和 virtualenv 结合使用
🛠️ pipx
简介:pipx 是由 PyPA 维护的工具,专注于在隔离的环境中安装和运行 Python 命令行应用。
功能:
- 在隔离的虚拟环境中安装 CLI 工具
- 运行一次性命令
优点:
- 避免全局污染,隔离性好
- 便于管理和运行 CLI 工具
缺点:
- 安装和运行速度较慢
- 功能专注于 CLI 工具管理,范围有限
适用场景:
- 需要在隔离环境中运行 CLI 工具
- 避免全局安装带来的依赖冲突
📦 poetry
简介:Poetry 是由 Python 社区开发的项目管理工具,旨在简化依赖管理和打包发布流程。
功能:
- 使用
pyproject.toml
管理项目依赖 - 自动创建和管理虚拟环境
- 构建和发布 Python 包
优点:
- 一体化管理项目生命周期
- 使用
pyproject.toml
,符合 PEP 518 标准
缺点:
- 依赖解析速度较慢
- 对 Python 版本管理支持有限
适用场景:
- 需要完整项目管理的开发者
- 希望简化构建和发布流程
🐍 pyenv
简介:pyenv 是由社区开发的工具,用于安装和管理多个 Python 版本。
功能:
- 安装和切换多个 Python 版本
- 支持全局和本地(每个项目)版本设置
优点:
- 支持多个 Python 版本的切换
- 适用于开发和测试不同版本的兼容性
缺点:
- 安装新版本需编译,耗时较长
- 不支持 Windows 系统
适用场景:
- 需要管理多个 Python 版本的开发者
- 测试不同 Python 版本的兼容性
🧪 virtualenv
简介:virtualenv 是由社区开发的工具,用于创建隔离的 Python 虚拟环境。
功能:
- 创建隔离的虚拟环境
- 支持不同项目使用不同的依赖
优点:
- 轻量级,创建环境速度快
- 适用于简单的项目隔离
缺点:
- 不包含依赖管理功能
- 需手动管理依赖
适用场景:
- 需要简单环境隔离的项目
- 与 pip 或 pip-tools 结合使用
⚡ uv
简介:uv 是由 Astral 公司开发的高性能 Python 包和项目管理器,使用 Rust 编写,旨在替代 pip、pip-tools、pipx、poetry、pyenv、virtualenv 等多个工具。
功能:
- 安装和管理 Python 包
- 创建和管理虚拟环境
- 安装和管理 Python 版本
- 运行和安装 CLI 工具
- 支持单文件脚本的依赖管理
- 提供与 pip 兼容的接口
优点:
- 安装速度快,性能优越
- 集成依赖管理、虚拟环境、Python 版本管理等功能
- 支持跨平台,兼容 macOS、Linux 和 Windows
缺点:
- 作为新兴工具,生态尚在发展中
适用场景:
- 需要高性能依赖解析和安装的项目
- 希望统一管理项目依赖、虚拟环境和 Python 版本
- 需要在隔离环境中运行 CLI 工具
功能/工具 | pip | pip-tools | pipx | poetry | pyenv | virtualenv | uv | |
---|---|---|---|---|---|---|---|---|
包安装 | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ | |
依赖锁定 | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ✅ | |
虚拟环境管理 | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | |
Python 版本管理 | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | |
CLI 工具管理 | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | |
构建与发布 | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ | |
安装速度 | 中 | 慢 | 慢 | 中 | 慢 | 快 | 快 | |
跨平台支持 | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
安装uv
uv 可以通过多种方式进行安装,以下是一些常见的安装方式:
- 使用官方独立安装器:
-
macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
-
Windows:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
- 通过 PyPI 安装:
-
使用 pip:
pip install uv
-
或使用 pipx:
pipx install uv
安装方式若使用独立安装器,可通过以下命令自更新至最新版:
uv self update
安装之后,可以通过uv help命令检查是否安装成功:
快速开始
uv 提供了 Python 开发所需的核心功能 —— 从安装 Python、运行简单脚本,到支持多版本、多平台的大型项目开发。
uv 的界面被分为多个功能模块,每个模块既可单独使用,也可组合使用。
🐍 Python 版本管理
用于安装和管理 Python 本身:
uv python install
:安装 Python 版本uv python list
:查看可用的 Python 版本uv python find
:查找已安装的 Python 版本uv python pin
:为当前项目固定使用某个 Python 版本uv python uninstall
:卸载某个 Python 版本
📄 脚本执行(Scripts)
用于执行独立的 Python 脚本,如 example.py
:
uv run
:运行脚本uv add --script
:为脚本添加依赖uv remove --script
:为脚本移除依赖
🧰 项目管理(Projects)
用于创建和维护包含 pyproject.toml
的 Python 项目:
uv init
:创建新项目uv add
:添加项目依赖uv remove
:移除项目依赖uv sync
:将项目依赖同步到虚拟环境中uv lock
:生成项目依赖的锁文件uv run
:在项目环境中运行命令uv tree
:查看依赖树uv build
:构建项目为可发布包uv publish
:将项目发布到 PyPI 等package index
🛠️ 工具管理(Tools)
用于运行和安装发布到 Python package indexes 的命令行工具(如 ruff
或 black
):
uvx
/uv tool run
:在临时环境中运行工具uv tool install
:安装工具到用户级环境uv tool uninstall
:卸载工具uv tool list
:列出已安装的工具uv tool update-shell
:更新 shell 以包含工具执行路径
🧩 pip 接口兼容层
用于手动管理包和环境,适用于传统流程或需要更低层控制的情况。
虚拟环境管理(替代 venv
和 virtualenv
):
uv venv
:创建新虚拟环境
包管理(替代 pip
和 pipdeptree
):
uv pip install
:安装包到当前环境uv pip show
:查看已安装包的信息uv pip freeze
:列出所有已安装包及版本uv pip check
:检查依赖兼容性uv pip list
:列出已安装包uv pip uninstall
:卸载包uv pip tree
:查看依赖树
依赖锁定(替代 pip-tools
):
uv pip compile
:将 requirements 编译为锁文件uv pip sync
:使用锁文件同步环境
🧹 实用命令(Utility)
用于管理 uv 的状态,如缓存、存储路径或自我更新等:
uv cache clean
:清理缓存条目uv cache prune
:清理过期缓存条目uv cache dir
:显示 uv 缓存目录uv tool dir
:显示工具安装目录uv python dir
:显示已安装的 Python 版本路径uv self update
:将 uv 更新到最新版本
uv安装python
如果你的系统中已经安装了 Python,uv 会自动检测并使用它,无需额外配置。不过,uv 也可以安装和管理 Python 版本。uv 会根据需要自动安装缺失的 Python 版本。
如果要安装最新版本的 Python:
uv python install
Python 并未发布官方的可分发二进制文件。因此,uv 使用了来自 Astral 的 python-build-standalone 项目的分发版。且,当 Python 通过 uv 安装时,它不会在全局环境中可用(即不能通过 python 命令直接调用)。
安装特定版本的 Python:
uv python install 3.12
要安装多个 Python 版本:
uv python install 3.11 3.12
要安装其他方的Python实现,例如 PyPy:
uv python install pypy@3.10
要重新安装 uv 管理的 Python 版本,请使用 --reinstall 选项,例如:
uv python install --reinstall
这将重新安装所有之前安装的 Python 版本。随着 Python 分发版的不断改进,重新安装可能会解决一些 bugs,即使 Python 版本未发生变化。
查看已安装的 Python 版本:
uv python list
使用 uv 时,Python 不需要显式安装。默认情况下,uv 会在需要时自动下载缺失的 Python 版本。例如,以下命令会在未安装 Python 3.12 时自动下载它:
uvx python@3.12 -c "print('hello world')"
即使未指定具体的 Python 版本,uv 也会按需下载最新版本。例如,如果系统中没有 Python 版本,以下命令将会在创建新虚拟环境之前先安装 Python:
uv venv
如果您的系统中已有 Python 安装,uv 会使用现有的 Python 安装。
uv运行脚本
Python 脚本是用于独立执行的文件,例如使用 python <script>.py
。使用 uv
运行脚本可以确保依赖项被妥善管理,而无需手动管理虚拟环境。
运行无依赖的脚本
如果脚本没有依赖项,可以使用以下方式运行:
example.py
print("Hello world")
运行:
uv run example.py
如果仅使用标准库模块,也无需额外操作:
import os
print(os.path.expanduser("~"))
uv run example.py
脚本也可以接收命令行参数:
example.py
import sys
print(" ".join(sys.argv[1:]))
uv run example.py test
uv run example.py hello world!
还可以通过标准输入传入脚本:
echo 'print("hello world!")' | uv run -
或者使用 shell 的 here-document:
uv run - <<EOF
print("hello world!")
EOF
如果是在带有 pyproject.toml
的项目目录中使用 uv run
,它会先安装当前项目依赖。若脚本与项目无关,可以加 --no-project
跳过:
uv run --no-project example.py
运行有依赖的脚本
如果脚本依赖于第三方库,它们需要被安装到脚本运行的环境中。uv
推荐按需创建环境,而不是维护一个长期存在的虚拟环境。这需要你显式声明依赖项。
例如,以下脚本依赖 rich
:
import time
from rich.progress import trackfor i in track(range(20), description="For example:"):time.sleep(0.05)
如果没有指定依赖,会运行失败:
uv run --no-project example.py
使用 --with
添加依赖:
uv run --with rich example.py
指定版本范围:
uv run --with 'rich>12,<13' example.py
重复使用 --with
可添加多个依赖。若在项目中运行,这些依赖会与项目依赖合并,如不想这样处理,可使用 --no-project
。
创建带元数据的 Python 脚本
Python 近期新增了 内联脚本元数据 的标准格式,可用来选择 Python 版本和声明依赖。用以下命令初始化脚本:
uv init --script example.py --python 3.12
添加依赖:
uv add --script example.py 'requests<3' 'rich'
脚本顶部会增加如下声明:
# /// script
# dependencies = [
# "requests<3",
# "rich",
# ]
# ///
示例:
import requests
from rich.pretty import pprintresp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])
执行:
uv run example.py
⚠️ 重要提示
使用内联元数据时,即使在项目中运行uv run
,也会忽略项目依赖,无需加--no-project
。
声明 Python 版本:
# /// script
# requires-python = ">=3.12"
# dependencies = []
# ///
type Point = tuple[float, float]
print(Point)
📌
dependencies
字段必须存在,即使为空。
如果所需版本未安装,uv
会自动下载。
使用 shebang 创建可执行文件
可在脚本开头添加 shebang,使其无需 uv run
直接执行:
#!/usr/bin/env -S uv run --scriptprint("Hello, world!")
赋予执行权限:
chmod +x greet
./greet
也支持声明依赖:
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = ["httpx"]
# ///
import httpx
print(httpx.get("https://example.com"))
使用其他package indexes
你可以通过 --index
指定依赖的包索引:
uv add --index "https://example.com/simple" --script example.py 'requests<3' 'rich'
这将在元数据中加入:
# [[tool.uv.index]]
# url = "https://example.com/simple"
锁定依赖
对于带 PEP 723 元数据的脚本,可以使用 uv lock
锁定依赖:
uv lock --script example.py
将创建 example.py.lock
文件。后续命令如 uv run --script
等将复用锁定版本。
提高可复现性
你可以在元数据中添加 exclude-newer
限制依赖的发布时间:
# /// script
# dependencies = [
# "requests",
# ]
# [tool.uv]
# exclude-newer = "2023-10-16T00:00:00Z"
# ///
指定不同的 Python 版本
每次运行脚本时可指定不同的 Python 版本:
import sys
print(".".join(map(str, sys.version_info[:3])))
运行:
uv run example.py
uv run --python 3.10 example.py
运行 GUI 脚本
在 Windows 上,.pyw
脚本会通过 pythonw
运行:
from tkinter import Tk, ttkroot = Tk()
root.title("uv")
frm = ttk.Frame(root, padding=10)
frm.grid()
ttk.Label(frm, text="Hello World").grid(column=0, row=0)
root.mainloop()
带依赖的 GUI 示例:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QGridLayoutapp = QApplication(sys.argv)
widget = QWidget()
grid = QGridLayout()label = QLabel("Hello World!")
grid.addWidget(label)widget.setLayout(grid)
widget.setGeometry(100, 100, 200, 50)
widget.setWindowTitle("uv")
widget.show()
sys.exit(app.exec_())
uv运行工具
许多 Python 包会提供可用作工具的应用程序。uv
对此提供了专门支持,使得调用和安装这些工具更加便捷。
运行工具
uvx
命令可以调用工具,而无需先安装它。
例如,要运行 ruff
:
uvx ruff
💡 注意
这实际上等价于:uv tool run ruff
uvx
是为了方便而提供的别名。
你可以在工具名称后添加参数:
uvx pycowsay hello from uv
使用 uvx
运行工具时,会将其安装在临时的、隔离的环境中。
💡 注意
如果你在一个项目中运行工具,而该工具要求你的项目已安装(例如使用pytest
或mypy
),请使用uv run
而非uvx
。否则,该工具会在一个与项目隔离的虚拟环境中运行。
如果你的项目是扁平结构(例如未使用src
目录),那么项目无需安装,uvx
就可以正常使用。在这种情况下,只有当你希望将工具版本固定在项目依赖中时,uv run
才更有意义。
包名与命令名不同的情况
当你运行 uvx ruff
时,uv
实际安装的是 ruff
包,该包提供了 ruff
命令。但有时包名和命令名不同。
你可以使用 --from
参数指定包名,例如:
uvx --from httpie http
指定版本运行工具
你可以使用 命令@<版本>
的形式运行特定版本的工具:
uvx ruff@0.3.0 check
运行最新版本:
uvx ruff@latest check
--from
同样支持版本指定:
uvx --from 'ruff==0.3.0' ruff check
或指定版本范围:
uvx --from 'ruff>0.2.0,<0.3.0' ruff check
⚠️ 注意:
@
语法只支持精确版本。
请求 extras(附加功能)
使用 --from
可以带上 extras:
uvx --from 'mypy[faster-cache,reports]' mypy --xml-report mypy_report
结合版本也可以:
uvx --from 'mypy[faster-cache,reports]==1.13.0' mypy --xml-report mypy_report
请求不同来源
--from
还支持从其他来源安装工具。
例如,从 Git 仓库:
uvx --from git+https://github.com/httpie/cli httpie
指定分支:
uvx --from git+https://github.com/httpie/cli@master httpie
指定 tag:
uvx --from git+https://github.com/httpie/cli@3.2.4 httpie
指定 commit:
uvx --from git+https://github.com/httpie/cli@2843b87 httpie
使用插件的命令
你也可以添加额外依赖,例如在运行 mkdocs
时附带 mkdocs-material
:
uvx --with mkdocs-material mkdocs --help
安装工具
如果某个工具经常使用,可以将其安装到持久环境中,并加入 PATH,而不是每次都用 uvx
调用。
💡 提示
uvx
是uv tool run
的别名。其它涉及工具的命令则需要完整的uv tool
前缀。
安装 ruff
:
uv tool install ruff
安装后,其可执行文件会放在 PATH 中的一个 bin
目录里,可以直接运行:
ruff --version
⚠️ 注意:
安装工具不会使其模块在当前环境中可导入。以下命令会失败:python -c "import ruff"
这种隔离有助于减少工具、脚本和项目依赖之间的冲突。
与 uvx
不同,uv tool install
操作的是包,会安装该包提供的所有可执行文件。
例如:
uv tool install httpie
会安装 http
, https
, httpie
等命令。
也可以带版本约束:
uv tool install 'httpie>0.1.0'
也支持从源安装:
uv tool install git+https://github.com/httpie/cli
支持附带额外包:
uv tool install mkdocs --with mkdocs-material
Ruff:极速的Python代码检查工具
这是一个由Rust编写的Python代码检查和格式化工具,致力于比现有的工具(如Flake8、Black)快10到100倍,并且集成了更多功能。无论你是Python开发者,还是开源项目的维护者,Ruff都能带给你惊人的提升。
Ruff 是一个极快的 Python 代码检查器和格式化工具,使用 Rust 语言编写,具备以下亮点:
- ⚡️ 极速性能:速度比现有工具(如 Flake8 和 Black)快 10 到 100 倍;
- 🐍 安装便捷:可通过
pip
安装,简单方便; - 🛠️ 支持配置:兼容
pyproject.toml
配置文件; - 🤝 兼容性强:完全支持 Python 3.13;
- ⚖️ 功能全面:对等支持 Flake8、isort 和 Black 的功能;
- 📦 内置缓存:智能缓存机制,避免重复分析未修改的文件;
- 🔧 自动修复:具备自动修复能力,如删除未使用导入等;
- 📏 规则丰富:内置 800+ 条规则,支持常用 Flake8 插件(如
flake8-bugbear
); - ⌨️ 编辑器集成:官方提供 VS Code 等主流编辑器插件;
- 🌎 Monorepo 友好:支持层次化和级联配置,适配大型项目结构。
Ruff 的目标是在性能上遥遥领先的同时,提供统一、强大且现代化的工具体验。它不仅能够取代 Flake8(及其多个插件)、Black、isort 等工具,而且可以以数十倍甚至上百倍的速度完成相同任务。
主要特点
- 🚀 极速性能:Ruff 的执行速度远超其他工具,甚至比 Pylint 快上 1000 倍。例如,在 Dagster(一个包含 25 万行代码的模块)上,Ruff 的运行时间仅为 0.4 秒,而 Pylint 则需要 约 2.5 分钟。
- 🌐 广泛的社区支持:Ruff 已被多个知名开源项目采用,如 Apache Airflow、FastAPI、Pandas、SciPy 等。
- ⚙️ 简洁配置:支持通过
pyproject.toml
、ruff.toml
或.ruff.toml
文件进行配置,默认配置已涵盖绝大多数常见错误。
Ruff 的安装与使用
-
使用
pip
安装:pip install ruff
-
使用
pipx
安装:pipx install ruff
-
使用
uv
工具安装:uv tool install ruff@latest # 全局安装 uv add --dev ruff # 添加到项目中
-
使用安装脚本(适用于 macOS 和 Linux):
curl -LsSf https://astral.sh/ruff/install.sh | sh
-
Windows PowerShell 安装:
powershell -c "irm https://astral.sh/ruff/install.ps1 | iex"
Ruff 的核心功能
-
🔍 代码检查(Linting):查找代码中的潜在错误并给出修复建议:
ruff check
-
🎨 代码格式化(Formatting):自动格式化代码,符合 PEP 8 等规范:
ruff format
-
🛠️ 自动修复:自动修复常见错误(如未使用的导入):
ruff check --fix
-
🧩 集成支持:支持 VS Code 插件,也可用作 GitHub Action 实现自动化工作流。
Ruff 支持 800+ 条规则,涵盖多个流行 Python 工具的功能,例如:
-
✨ 自动修复:如删除未使用的导入(类似
autoflake
); -
🔒 安全检查:如检测潜在安全风险(基于
flake8-bandit
); -
📈 代码优化:增强类型检查、API 使用建议等;
-
📋 代码质量检查:
flake8-bugbear
flake8-commas
flake8-docstrings
flake8-import-conventions
flake8-logging
- 等等
升级工具
升级工具使用:
uv tool upgrade ruff
如果之前安装时使用了版本范围(如 ruff >=0.3,<0.4
),则升级会遵循该范围。
若想替换约束,可重新安装:
uv tool install ruff>=0.4
升级所有已安装工具:
uv tool upgrade --all
指定 Python 版本
默认情况下,uv
会使用系统默认的 Python 解释器。
你可以使用 --python
显式指定:
运行工具时:
uvx --python 3.10 ruff
安装工具时:
uv tool install --python 3.10 ruff
升级工具时:
uv tool upgrade --python 3.10 ruff
uv项目管理
uv 支持管理基于 pyproject.toml 的 Python 项目依赖。
你可以使用 uv init
命令创建一个新的 Python 项目:
uv init hello-world
cd hello-world
或者,在当前工作目录中初始化项目:
mkdir hello-world
cd hello-world
uv init
uv
会创建以下文件结构:
.
├── .python-version
├── README.md
├── main.py
└── pyproject.toml
其中,main.py
包含一个简单的 “Hello world” 程序。你可以通过以下命令运行它:
uv run main.py
项目结构说明
一个项目由多个关键部分组成,uv
会在首次运行如 uv run
、uv sync
或 uv lock
等命令时创建虚拟环境和 uv.lock
文件。
完整的结构如下所示:
.
├── .venv
│ ├── bin
│ ├── lib
│ └── pyvenv.cfg
├── .python-version
├── README.md
├── main.py
├── pyproject.toml
└── uv.lock
pyproject.toml
该文件包含项目的元数据:
[project]
name = "hello-world"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
dependencies = []
你可以在这个文件中指定依赖项,也可以配置描述、许可证等项目信息。它可以手动编辑,也可以通过命令行使用 uv add
和 uv remove
来管理依赖。
此外,也可以通过 [tool.uv]
部分在该文件中设置 uv
的配置选项。
.python-version
该文件指定项目默认使用的 Python 版本,uv
会据此创建虚拟环境。
.venv
这是项目的虚拟环境目录,uv
会将所有依赖安装在此处,确保项目与系统环境隔离。
uv.lock
这是跨平台的锁文件,记录项目的精确依赖版本,用于确保在不同机器上可重复、可一致地安装环境。
与 pyproject.toml
(描述依赖要求)不同,uv.lock
中存储的是实际安装的解析版本。
注意:该文件是可读的 TOML 文件,但应由 uv
自动维护,不建议手动编辑。
依赖管理
使用 uv add
添加依赖项(会同步更新锁文件和虚拟环境):
uv add requests
你也可以添加特定版本或指定源码地址:
uv add 'requests==2.31.0'
uv add git+https://github.com/psf/requests
从 requirements.txt
迁移时,可以使用 -r
参数:
uv add -r requirements.txt -c constraints.txt
移除依赖包:
uv remove requests
升级某个依赖包:
uv lock --upgrade-package requests
该命令将尝试将指定包更新为最新兼容版本,同时保持其他依赖不变。
运行命令
uv run
可在项目虚拟环境中执行任意脚本或命令。
每次运行前,uv
会自动验证 lockfile
是否与 pyproject.toml
同步,并保持环境一致,无需手动干预,确保你始终运行在一致的锁定环境中。
例如,使用 flask:
uv add flask
uv run -- flask run -p 3000
运行脚本:
# example.py
import flask
print("hello world")
uv run example.py
也可以手动同步环境并激活虚拟环境后再运行命令:
macOS / Linuxuv sync
source .venv/bin/activate
flask run -p 3000
python example.pyWindowsuv sync
.venv\Scripts\activate
flask run -p 3000
python example.py
注意:若未使用
uv run
,必须先激活虚拟环境,不同操作系统和 shell 的激活方式不同。
构建发行包
使用 uv build
可构建源码包和 wheel 包,构建产物将默认保存在 dist/
目录:
uv build
ls dist/
uv构建和发布包
uv
支持通过 uv build
将 Python 项目打包为源码分发包(source distribution)和二进制分发包(wheel),并通过 uv publish
上传到包注册中心(如 PyPI)。
在发布项目之前,你需要确保项目已经准备好进行分发打包。
如果你的 pyproject.toml
中没有定义 [build-system]
,那么 uv
默认不会为你构建项目。这通常意味着项目尚未准备好进行分发。
注意:
如果你有不希望发布的内部包,可以将其标记为私有:
[project]
classifiers = ["Private :: Do Not Upload"]
该设置会让 PyPI 拒绝你上传的包,但不会影响其他注册中心的安全或隐私设置。
官方还建议使用每个项目专属的 token。没有匹配该项目的 PyPI token,包就不会被意外发布。
构建你的包
使用以下命令构建包:
uv build
默认情况下,uv build
会构建当前目录下的项目,并将构建产物放入 dist/
子目录中。
你也可以指定目录或包进行构建:
uv build <SRC> # 构建指定目录下的包
uv build --package <PACKAGE> # 构建当前工作区中的指定包
提示:
默认情况下,uv build
会在解析构建依赖时使用 pyproject.toml
中 [tool.uv.sources]
的配置项。
为了确保在禁用 tool.uv.sources
(如使用 pypa/build
等其他构建工具)时依然能正确构建包,建议发布前使用:
uv build --no-sources
发布你的包
使用以下命令将包发布到注册中心:
uv publish
你可以通过命令行或环境变量设置发布凭证:
- 使用
--token
或UV_PUBLISH_TOKEN
- 或使用
--username
/UV_PUBLISH_USERNAME
和--password
/UV_PUBLISH_PASSWORD
如果你从 GitHub Actions 发布到 PyPI,则无需设置凭证,只需将其添加为 受信任的发布者 即可。
注意:
PyPI 现在不再支持使用用户名和密码发布包,你必须使用 token。使用 token 相当于设置:
--username __token__
--password <your-token>
如果你使用自定义的索引地址(例如 TestPyPI),需在 pyproject.toml
中添加如下配置,并使用 --index
指定:
[[tool.uv.index]]
name = "testpypi"
url = "https://test.pypi.org/simple/"
publish-url = "https://test.pypi.org/legacy/"
explicit = true
例如:
uv publish --index testpypi
注意:
使用 uv publish --index <name>
时必须存在 pyproject.toml
文件,也就是说 CI 中发布任务必须包含项目代码 checkout 步骤。
虽然 uv publish
会自动重试失败的上传,但发布过程中可能仍会出现部分文件已上传、部分失败的情况。
对于 PyPI,你可以直接重复执行相同命令,重复文件会被忽略。
对于 其他注册中心,使用 --check-url <index url>
指定检查 URL(即索引地址而非发布地址)。uv
会跳过重复上传并能处理并发上传时的冲突。
注意:检查时,已上传文件必须与之前完全一致,否则会报错(避免同版本包的源码与 wheel 不一致)。
安装测试
可以使用以下命令测试包是否能被成功安装和导入:
uv run --with <PACKAGE> --no-project -- python -c "import <PACKAGE>"
--no-project
标志可避免从当前目录中安装本地项目。
提示:
如果你刚刚安装了该包,为了避免使用缓存版本,可添加:
--refresh-package <PACKAGE>
总结
uv 的设计初衷是为了解决传统 Python 包管理工具在性能和功能整合方面的不足。它特别适用于以下场景:(CSDN博客)
-
大型项目或团队协作:在需要管理复杂依赖关系和多个开发环境的项目中,uv 的统一管理和快速安装特性可以显著提高效率。(CSDN博客)
-
频繁构建和部署的项目:对于需要频繁构建和部署的项目,uv 的快速依赖解析和安装能力可以节省大量时间。(CSDN博客)
-
需要严格依赖锁定的项目:uv 提供了跨平台的锁定文件(uv.lock),确保在不同环境中安装一致的依赖版本,提升项目的可重复性和稳定性。(CSDN博客)
-
希望简化工具链的开发者:uv 集成了 pip、virtualenv、pip-tools 等工具的功能,减少了工具之间的切换,提高了开发效率。
尽管 uv 在性能和功能整合方面表现出色,但对于追求开发自由度的个人开发者来说,可能会感受到以下限制:
-
自动化程度高:uv 自动管理虚拟环境和依赖,可能会让习惯手动配置的开发者感到不适应。
-
依赖 pyproject.toml:uv 主要依赖 pyproject.toml 进行配置,对于习惯使用 requirements.txt 的开发者来说,可能需要调整使用习惯。
-
学习成本:虽然 uv 兼容 pip 的命令,但要充分利用其全部功能,仍需花时间学习其新的命令和工作流程。
综上,对于uv的强大我是持肯定态度的,他提供了比pip更快速的包安装和包管理,提供了比venv,venvwrapper等更方便的虚拟环境管理,更将pip-tools、pipx、poetry、pyenv、virtualenv这些乱七八糟的工具统一化!
uv的确是个好工具,但对于项目构建,我目前还是习惯freeze一个requirement.txt然后在Dockerfile里面写:
RUN pip install -r requirement.txtCMD ["python","main.py"]
然后使用helm去部署我的大型服务。其次对于脚本文件执行,能用python script.py
为什么还要使用uv run script.py
,uv是一个辅助工具并不是一个rust写的python解释器。
个人还是倾向于自由化的开发…^_^