uv全功能更新:管理Python项目、工具、脚本和环境的终极解决方案
off999 2025-08-01 20:07 35 浏览 0 评论
花下猫语:uv 项目自发布起就大受欢迎,目前 Github star 52.6 K,远超过它的同类竞品们。前不久,它的创始人在 X 上披露了一组惊人的数据:uv 曾占据了 PyPI 超过 20% 的流量,用户每天通过它发起约 4-5 亿次下载请求!
我在去年翻译过 uv 首发时的新闻文章,根据博客后台不完整的统计,从 Google 搜索进入的访问量已经超过 3000,妥妥成为了我博客的搜索访问 TOP 1!这侧面也反映出 uv 的火爆程度!
uv 刚过一周岁不久,如此年轻,成绩斐然啊。趁着这波热点(实际是假期有时间),我抽空把 uv 重要版本更新的文章也翻译出来了,enjoy reading~
作者:@charliermarsh
译者:豌豆花下猫@Python猫
英文:uv: Unified Python packaging (
https://astral.sh/blog/uv-unified-python-packaging)
声明:本翻译是出于交流学习的目的,为便于阅读,部分内容略有改动。转载请保留作者信息。
简述: uv 是一个用 Rust 开发的超高性能 Python 包管理器。
我们最初在 2 月份发布了 uv,作为常见 pip 工作流的即插即用替代方案。(译注:uv 在 2024.02 发布,本文写于 2024.08,翻译于 2025.05)
今天,我们发布一系列新功能,这些功能将 uv 从一个 pip 替代品扩展成为一个端到端的解决方案,可用于管理 Python 项目、命令行工具、单文件脚本,甚至 Python 本身。
它就像是 Python 世界的Cargo:提供了一个快速、可靠且易用的统一接口。
在 Astral,我们致力于为 Python 生态系统打造高性能的开发工具。我们最知名的产品是 Ruff,一个超高速的 Python 代码检查器 和 格式化工具。
在 2 月份,我们发布了 uv,这是一个极快的 Python 包安装器和依赖解析器,最初设计为常见 pip 工作流的即插即用替代方案。
今天,我们宣布 uv 自首次发布以来最大规模的功能扩展:
- 端到端项目管理:uv run、uv lock 和 uv sync。uv 现在能基于标准元数据创建跨平台的锁文件,并利用该文件来安装依赖。它是 Poetry、PDM 和 Rye 等工具的高性能替代品。
- 工具管理:uv tool install 和 uv tool run (别名为 uvx)。uv 能在隔离的虚拟环境中安装命令行工具,还能无需先安装就直接执行命令(如 uvx ruff check)。它是 pipx 等工具的高性能替代品。
- Python 安装:uv python install。uv 现在可以直接帮你安装 Python,替代 pyenv 等工具。
- 脚本执行:uv 现在可以管理基于 PEP 723 标准的单文件 Python 脚本,这些脚本内部包含依赖元数据。只需要一个简单的 uv run 命令就能执行这些独立的 Python 脚本。
...所有功能背后都是一个跨平台的超高速依赖解析器在支撑。
上图展示了启用所有可选依赖项时解析 Transformers 项目的速度对比:上方无缓存状态,下方启用了缓存。
并且所有功能都包含在新的、全面的文档中。
这些新功能每一项都大大扩展了 uv 的能力范围。但更独特的是,它们组合起来形成了一个完整的工具链,大大简化了 Python 开发过程。
结合 uv pip(我们将它作为一等功能,继续维护并改进),uv 适用于任何 Python 工作流,从一次性脚本到大型的多包工作区开发。
你可以通过我们的独立安装程序或从 PyPI 安装 uv:
curl
curl -LsSf https://astral.sh/uv/install.sh | sh
win
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
pip
pip install uv
pipx
pipx install uv
项目
uv 现在可以全面管理 Python 项目了。如果你用过 Poetry、PDM 或 Rye,那么 uv 的项目 API 对你来说一定不陌生。
项目 API 基于 Python 标准构建,使用 pyproject.toml 来定义项目元数据。
例如,你可以运行 uv init && uv add "fastapi>=0.112" 生成以下内容:
[project]
name = "hello-world"
version = "0.1.0"
readme = "README.md"
dependencies = ["fastapi>=0.112"]
从它开始,uv 将基于项目的依赖项创建一个锁文件。以下是一个示例片段:
[[package]]
name = "fastapi"
version = "0.112.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pydantic" },
{ name = "starlette" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/2c/09/71a961740a1121d7cc90c99036cc3fbb507bf0c69860d08d4388f842196b/fastapi-0.112.1.tar.gz", hash = "sha256:b2537146f8c23389a7faa8b03d0bd38d4986e6983874557d95eed2acc46448ef", size = 291025 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/39/b0/0981f9eb5884245ed6678af234f2cbcd40f44570718caddc0360bdb4015d/fastapi-0.112.1-py3-none-any.whl", hash = "sha256:bcbd45817fc2a1cd5da09af66815b84ec0d3d634eb173d1ab468ae3103e183e4", size = 93163 },
]
[[package]]
name = "fastapi-cli"
version = "0.0.5"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "typer" },
{ name = "uvicorn", extra = ["standard"] },
]
sdist = { url = "https://files.pythonhosted.org/packages/c5/f8/1ad5ce32d029aeb9117e9a5a9b3e314a8477525d60c12a9b7730a3c186ec/fastapi_cli-0.0.5.tar.gz", hash = "sha256:d30e1239c6f46fcb95e606f02cdda59a1e2fa778a54b64686b3ff27f6211ff9f", size = 15571 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/24/ea/4b5011012ac925fe2f83b19d0e09cee9d324141ec7bf5e78bb2817f96513/fastapi_cli-0.0.5-py3-none-any.whl", hash = "sha256:e94d847524648c748a5350673546bbf9bcaeb086b33c24f2e82e021436866a46", size = 9489 },
]
uv 的锁文件就像项目依赖关系的完整快照,它能确保项目在不同机器上的运行环境保持一致。
这个锁文件最大的优势是跨平台。不管你在哪个系统上生成锁文件,它都能在其它平台上正常工作。uv 为每个平台定义了一个独特的解决方案,生成一个可读且可审计的锁文件,精确地定义了将安装哪些软件包。
例如:如果你在 macOS 上运行 uv lock,uv 仍然会为 Linux 和 Windows 生成解析方案,即使每个平台上所需的依赖集稍有不同。
而且它做得非常快。在没有任何缓存的情况下,uv 可以在大约半秒钟内解析 Jupyter 项目的依赖项(在缓存预热的情况下约为 20 毫秒)。
解析 Jupyter 项目时无缓存(上)和有缓存(下)的对比。
项目 API 的核心是 uv run 命令,它能在项目专属环境中运行命令,而且不需要手动激活虚拟环境。
uv run 非常快速。每次执行时,它都会自动重新锁定和同步项目,确保你的环境始终是最新状态。完全不需要手动干预。
换句话说,uv run 能确保你的命令每次都在一个一致的、受锁文件管理的环境中运行。
使用 uv run 命令启动 FastAPI 应用的示例。
有了 uv run,你再也不需要操心虚拟环境的激活、依赖包的管理或者项目的维护更新。一切都变得无比简单。
想了解更多详情,请查阅项目文档。
本文翻译并首发于 Python猫:uv:统一的 Python 包管理
依赖源:可编辑依赖、相对路径等
uv 基于 Python 标准构建,如 PEP 621。同时,它还添加了一些在标准中没有的功能,这些功能对本地开发至关重要,如相对路径和可编辑依赖。
在标准的 project.dependencies 部分,你可以定义项目的依赖和可发布的元数据。而在开发过程中,uv 还允许你通过 tool.uv.sources 为这些依赖项指定替代来源。
例如,要使用本地的、可编辑版本的 anyio,你可以运行 uv add --editable ../anyio 来生成以下 pyproject.toml:
[project]
name = "hello-world"
version = "0.1.0"
readme = "README.md"
dependencies = ["anyio"]
[tool.uv.sources]
anyio = { path = "../anyio", editable = true }
当发布到 PyPI 时,上述包会声明对anyio 的依赖。但在本地开发时,使用 uv run 可以将 ../anyio 路径下的可编辑的包加到开发环境中。这样,项目的依赖定义保持不变,只是依赖的来源发生了变化。
详细内容请查阅依赖源文档。
工作区
受 Cargo 相同概念的启发,uv 支持工作区:一组管理在一起的包的集合。
想象这样一个场景:在同一个 Git 仓库中,有一个使用 FastAPI 构建的 Web 应用,还有多个作为独立 Python 包开发和维护的库。
大多数大型 Python 项目最终都会用自己的方式来实现这个概念,它们通常借助手写脚本和自定义工具来管理各个包之间的关系。
uv 的工作区 API 为大规模开发中的各种挑战提供了一致、高效且具有创新性的解决方案。
在工作区中,每个包都有自己的 pyproject.toml,但工作区共享一个锁文件,确保工作区使用一致的依赖集运行。
[project]
name = "fastapi"
version = "0.1.0"
readme = "README.md"
dependencies = ["uvicorn"]
[tool.uv.sources]
uvicorn = { workspace = true }
[tool.uv.workspace]
members = ["libraries/*"]
在工作区的根目录下,你可以运行命令来操作任何工作区包。例如,执行 uv run --package fastapi 或 uv run --package uvicorn。
更多细节,请查阅工作区文档。
本文翻译并首发于 Python猫:(
https://pythoncat.top/posts/2025-05-05-uv)
工具
uv 现在有两种新能力:
- 通过 uv tool install 在专用的隔离虚拟环境中安装命令行工具(如 Ruff)
- 通过 uvx 直接运行一次性命令,无需预先安装
如果你使用过 pipx 或 npx,你会发现 uv 的工具 API 很熟悉。
比如,输入 uvx posting 就能直接运行 Darren Burns 开发的 posting 终端界面程序(TUI)。
使用 uvx 命令在终端中运行 posting 的示例。
工具 API 让你能集中管理系统上的 Python 工具。你可以:
- 用 uv tool list 查看所有已安装的工具及其可执行文件
- 用 uv tool upgrade --all 将所有工具升级到最新版本
uv 的工具 API 非常快,通过 uvx 执行命令几乎没有任何额外开销。
更多工具功能,请查阅工具文档。
Python 引导安装
uv 现在能够安装和管理 Python 本身,使其完全自引导:
$ curl -LsSf https://astral.sh/uv/install.sh | sh
$ uv python install 3.12
如果你的机器上没有安装 Python,或者缺少特定的、所需的 Python 版本,除了显式调用 uv python 外,uv 还可以根据需要,自动下载所需的 Python 版本(如 uv run、uv venv 等命令)。
例如,以下是在新的 Ubuntu Docker 镜像上运行 posting 所需的全部命令,没有任何隐藏步骤:
$ apt-get update && apt-get install -y curl
$ curl -LsSf https://astral.sh/uv/install.sh | sh
$ source $HOME/.cargo/env
$ uvx posting
当你运行 uvx 命令时,uv 会一步到位地完成所有工作:
- 安装 Python 3.12.4(文章写作时的最新稳定版本)
- 创建虚拟环境
- 安装必要的依赖包
- 启动 posting 程序
整个过程无缝衔接,高效快捷。
单文件脚本
最后:uv 现在提供了对单文件 Python 脚本的一等支持,这些脚本可以内嵌依赖元数据,完全符合 PEP-723 标准。
例如,以下文件 main.py,它从 Python 增强提案索引中获取前 10 个 PEP:
import requests
from rich.pretty import pprint
resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])
这个脚本依赖requests 和 rich,但不包含任何显式的依赖元数据。早些时候,你需要单独管理这些依赖项,例如使用专门的 requirements.txt 文件。
现在,你可以使用 uv add 自动将依赖声明嵌入到脚本中:
$ uv add --script main.py "requests<3" "rich"
$ cat main.py
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "requests<3",
# "rich",
# ]
# ///
import requests
from rich.pretty import pprint
resp = 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 main.py 将在一个隔离的、临时的虚拟环境中执行脚本,并安装所有依赖项。
使用 uv run 执行带有内嵌依赖项的单文件脚本的示例。
你也可以使用--with 标记在运行时指定依赖项,例如:uv run --with "requests<3" --with rich main.py。
有了 uv 的 Python 引导安装功能,你只需要 uv 就可以运行封闭式的、可重分发的单文件 Python 脚本,再也不用担心虚拟环境、包管理或 Python 版本的问题。
更多细节,请查阅脚本文档。
为规模化而构建
在 Astral,我们的指导原则之一是:“为所有人设计,为规模化构建(Design for everyone, build for scale)。”
我们希望打造的工具对初学者友好,但同时又能满足最大型 Python 项目的需求。
我们相信 uv 已经很好地实现了这两个目标。
如果你在组织里使用 uv,并想一起解决 Python 生态的包管理挑战,欢迎联系我们。让我们携手共创更好的工具。
附录
用 Rust 开发的 Python 包管理工具 uv,可替换 pip、pip-tools 和 virtualenv
相关推荐
- Linux 网络协议栈_linux网络协议栈
-
前言;更多学习资料(包含视频、技术学习路线图谱、文档等)后台私信《资料》免费领取技术点包含了C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,Z...
- 揭秘 BPF map 前生今世_bpfdm
-
1.前言众所周知,map可用于内核BPF程序和用户应用程序之间实现双向的数据交换,为BPF技术中的重要基础数据结构。在BPF程序中可以通过声明structbpf_map_def...
- 教你简单 提取fmpeg 视频,音频,字幕 方法
-
ffmpeg提取视频,音频,字幕方法(HowtoExtractVideo,Audio,SubtitlefromOriginalVideo?)1.提取视频(ExtractVi...
- Linux内核原理到代码详解《内核视频教程》
-
Linux内核原理-进程入门进程进程不仅仅是一段可执行程序的代码,通常进程还包括其他资源,比如打开的文件,挂起的信号,内核内部的数据结构,处理器状态,内存地址空间,或多个执行线程,存放全局变量的数据段...
- Linux C Socket UDP编程详解及实例分享
-
1、UDP网络编程主要流程UDP协议的程序设计框架,客户端和服务器之间的差别在于服务器必须使用bind()函数来绑定侦听的本地UDP端口,而客户端则可以不进行绑定,直接发送到服务器地址的某个端口地址。...
- libevent源码分析之bufferevent使用详解
-
libevent的bufferevent在event的基础上自己维护了一个buffer,这样的话,就不需要再自己管理一个buffer了。先看看structbufferevent这个结构体struct...
- 一次解决Linux内核内存泄漏实战全过程
-
什么是内存泄漏:程序向系统申请内存,使用完不需要之后,不释放内存还给系统回收,造成申请的内存被浪费.发现系统中内存使用量随着时间的流逝,消耗的越来越多,例如下图所示:接下来的排查思路是:1.监控系统中...
- 彻底搞清楚内存泄漏的原因,如何避免内存泄漏,如何定位内存泄漏
-
作为C/C++开发人员,内存泄漏是最容易遇到的问题之一,这是由C/C++语言的特性引起的。C/C++语言与其他语言不同,需要开发者去申请和释放内存,即需要开发者去管理内存,如果内存使用不当,就容易造成...
- linux网络编程常见API详解_linux网络编程视频教程
-
Linux网络编程API函数初步剖析今天我们来分析一下前几篇博文中提到的网络编程中几个核心的API,探究一下当我们调用每个API时,内核中具体做了哪些准备和初始化工作。1、socket(family...
- Linux下C++访问web—使用libcurl库调用http接口发送解析json数据
-
一、背景这两天由于一些原因研究了研究如何在客户端C++代码中调用web服务端接口,需要访问url,并传入json数据,拿到返回值,并解析。 现在的情形是远程服务端的接口参数和返回类型都是json的字符...
- 平衡感知调节:“系统如人” 视角下的架构设计与业务稳定之道
-
在今天这个到处都是数字化的时代,系统可不是一堆冷冰冰的代码。它就像一个活生生的“数字人”,没了它,业务根本转不起来。总说“技术要为业务服务”,但实际操作起来问题不少:系统怎么才能快速响应业务需求?...
- 谈谈分布式文件系统下的本地缓存_什么是分布式文件存储
-
在分布式文件系统中,为了提高系统的性能,常常会引入不同类型的缓存存储系统(算法优化所带来的的效果可能远远不如缓存带来的优化效果)。在软件中缓存存储系统一般可分为了两类:一、分布式缓存,例如:Memca...
- 进程间通信之信号量semaphore--linux内核剖析
-
什么是信号量信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)所拥有。信号量的值为正的时候,说明它空闲。所测试的线程可以锁定而使用它。若为0,说明它被占用,测试的线程要进入睡眠...
- Qt编写推流程序/支持webrtc265/从此不用再转码/打开新世界的大门
-
一、前言在推流领域,尤其是监控行业,现在主流设备基本上都是265格式的视频流,想要在网页上直接显示监控流,之前的方案是,要么转成hls,要么魔改支持265格式的flv,要么265转成264,如果要追求...
- 30 分钟搞定 SpringBoot 视频推拉流!实战避坑指南
-
30分钟搞定SpringBoot视频推拉流!实战避坑指南在音视频开发领域,SpringBoot凭借其快速开发特性,成为很多开发者实现视频推拉流功能的首选框架。但实际开发中,从环境搭建到流处理优...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)