现在是 2025 年了,安装 Python、管理虚拟环境以及同步同事之间的依赖关系真的有必要这么麻烦吗?其实不必!最近,一个名为 uv 的出色新工具问世了,它彻底改变了安装和使用 Python 的便捷性。
uv 是一个由 Astral(一家小创业公司)开发的免费、开源工具,Astral 在过去几年中一直致力于开发 Python 工具,如优秀的 linter Ruff。uv 可以:
最棒的是,它可以比其他任何工具都更好地完成上述所有任务。在我看来,它极其快速,使用 Rust 编写,几乎可以在任何操作系统或平台上运行。
uv 的安装非常直接。有几种方法,但我认为最简单的是这个一行命令 - 对于 Linux 和 Mac,它是:
curl -LsSf https://astral.sh/uv/install.sh | sh
或者在 Windows 的 powershell 中:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
然后,您可以使用 uv 命令访问 uv。安装 uv 不会干扰您现有的任何 Python 安装 - 它是一个独立的工具,因此可以安全地安装它来试用。
对于任何 Python 项目,与虚拟环境一起工作都是一个好主意。它将不同的代码和依赖项彼此隔离,根据我的经验,及早养成使用虚拟环境的习惯可以为您节省很多麻烦。uv 自然地使用虚拟环境,因此如果您开始使用 uv,很容易开始使用它们。
uv 将根据您正在工作的目录(或父目录)中的 pyproject.toml 文件为您构建 Python 环境。pyproject.toml 文件是一种标准、现代的格式,用于指定 Python 项目的依赖项。一个基本的示例可能如下所示:
[project]
name = "my_project"
version = "1.0.0"
requires-python = ">=3.9,<3.13"
dependencies = [
"astropy>=5.0.0",
"pandas>=1.0.0,<2.0",
]
本质上,它只需要指定使用哪个 Python 版本和一些依赖项。添加名称和版本号也不错。
(附注:对于您发布的软件包,例如发布到 pip 和 uv 使用的 Python Package Index,pyproject.toml 文件是一种现代方式,可以指定发布软件包所需的一切。)
使用 uv 启动新 Python 项目,您可以运行
uv init
这将为您创建一个新项目,包含 pyproject.toml、README.md 等重要的样板文件。
运行此命令有很多不同方式,例如 uv init --bare(仅创建 pyproject.toml),uv init --package(设置新 Python 软件包),等等。我建议运行 uv init --help 来了解它们。
一旦您初始化一个项目 - 或者如果您已经在项目中有一个 pyproject.toml 文件 - 使用 uv 非常容易。您只需在包含 pyproject.toml 文件的目录中运行
uv sync
此命令(实际上,如果您尚未运行,大多数 uv 命令也是如此)将:
.venvuv.lock 文件,该文件保存安装的每个软件包的精确、平台无关版本 - 意味着其他同事可以完全复制您的 Python 环境。原则上,您可以像使用其他工具可能看到的典型虚拟环境一样“激活”这个新虚拟环境,但使用 uv 最“uv-onic”的方式是简单地在任何命令前加上 uv run。此命令会自动为您选择正确的虚拟环境并使用它运行命令。例如,要运行脚本 - 而不是
source .venv/bin/activate
python myscript.py
您可以直接运行
uv run myscript.py
具有相同的效果。同样,要使用 Jupyter Lab 这样的“工具”,您可以直接运行
uv run jupyter lab
在您的项目目录中,而不是先“激活”环境,然后再单独运行 jupyter lab。
您始终可以手动编辑 pyproject.toml 文件:uv 将检测更改并重建项目的虚拟环境。但 uv 也有更简单的方式添加依赖项 - 您只需运行
uv add numpy >= 2.0
添加软件包,包括指定版本约束(如下所示)。此命令会自动为您编辑 pyproject.toml。uv add 也非常强大,适用于从 git 或计算机上的其他位置添加远程依赖项(但我在这里不深入讨论)。
最后,我认为 uv 可以做的最有用的事情之一是为您的项目锁定特定的 Python 版本。运行
uv python pin 3.12.9
将为您锁定当前项目以使用 完全 的 Python 3.12.9,对于其他使用 uv 的人也是如此 - 意味着您确实可以在多台机器上复制 完全 相同的 Python 安装。
但有时,您可能只想快速运行一个工具 - 例如,在某处使用 Ruff 检查代码,或在没有环境的情况下启动 Jupyter 笔记本服务器,甚至只需快速启动一个安装了 pandas 的 IPython 会话,以便打开一个文件。uv tool run 命令,其简写为 uvx,使得这变得非常容易。运行如下命令
uvx ruff
将自动下载您要使用的工具,并在一次性虚拟环境中运行它。 一旦该工具之前已被下载,由于 uv 使用缓存,这将非常快速。
我可能需要这样做的情况很多 - 一个常见的例子可能是快速启动一个安装了 pandas 的 IPython 会话(使用 --with 添加依赖项),以便快速打开和查看 parquet 文件。例如:
uvx --with pandas,pyarrow ipython
或者,只是启动一个 Jupyter Lab 服务器,以便我可以快速打开学生发送给我的 Jupyter 笔记本:
uvx --from jupyter-core jupyter lab
或者,实际上是许多其他奇怪的一次性用例,其中 uvx 真的很好用。我并不觉得自己因为总是使用虚拟环境而错失了什么,因为 uvx 始终为您提供一张“免费出狱卡”,在您需要时。
我去年第一次发现了 uv,当时与我们的其他开发人员一起合作构建 The Astrosky Ecosystem - 一个为天文学家在线构建开源社交媒体集成的精彩项目。但是,由于多位开发人员在多个操作系统上异步工作,管理 Python 安装迅速成为一项巨大的任务。
uv 对我们来说是一个极其强大的简化工具,我们将其用于整个技术栈。作为开发人员,我们可以共同使用相同的 Python 安装,这在我们使用具有破坏性更改的多个半实验性依赖项时尤为重要。在 GitHub Actions 上,我们计划使用 uv 快速构建 Python 环境并运行我们的单元测试。在生产环境中,uv 已经为我们的所有服务器管理 Python。
知道 Python 和软件包安装在我们所有的机器上始终会一致且正确地处理,真的很好。这就是为什么 uv 是过去十年里 Python 生态系统中发生的最棒的事情。