Python 包管理工具 UV

UV 是一个第三方 Python 包管理工具,可以替代官方的 pip。

其优点是速度快、可以切换多个版本的 python、管理第三方包的虚拟环境等。更多内容可以看官方文档

安装

Windows:

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

Linux/Mac OS:

curl -LsSf https://astral.sh/uv/install.sh | sh

uv 的运行程序安装在C:\Users\70748\.local\bin,要将其添加到环境变量 path。

输入以下命令可以查看 uv 的帮助文档:

uv help

Python 管理

可以用 uv 下载和管理 Python。

查看 uv 支持的 Python 版本:

uv python list

会列出当前电脑安装的 Python 版本以及可以安装的 Python 版本:

image-20250812113858339

可以使用以下命令安装特定版本的 python:

uv python install 3.13.6

如果不指定版本号,将安装最新版本的 python。

安装好后再使用 uv 查看 python 列表:

image-20250812114630023

同样被安装到.local\bin目录,因此可以直接通过命令行启动对应版本的 python:

❯ python3.13
Python 3.13.6 (main, Aug  8 2025, 17:02:53) [MSC v.1944 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> exit

也可以通过 uv run命令运行指定版本的 python:

❯ uv run -p 3.13 python
Python 3.13.6 (main, Aug  8 2025, 17:02:53) [MSC v.1944 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> exit

效果是相同的。

运行脚本

创建一个简单的 Python 脚本:

print('Hello World')

如果是执行脚本而非启动 Python 的交互界面:

❯ python3.13 .\hello.py
Hello World

❯ uv run .\hello.py
Hello World

如果脚本不包含依赖或者只包含官方;依赖,这么做没有什么问题,如果包含的是第三方依赖:

import time
from rich.progress import track

for i in track(range(20), description="For example:"):
    time.sleep(0.05)

这里使用第三方依赖 rich 在控制台输出一个进度条。

直接执行会报错:

uv run .\test.py
Traceback (most recent call last):
  File "D:\workspace\learn-python\rich.py", line 2, in <module>
    from rich.progress import track
  File "D:\workspace\learn-python\rich.py", line 2, in <module>
    from rich.progress import track
ModuleNotFoundError: No module named 'rich.progress'; 'rich' is not a package

因为环境缺少第三方库,需要安装库后才能正常运行。

可以在执行 run 命令时通过参数指定脚本运行需要的第三方库,这样如果环境缺少第三方库就会安装后再执行脚本:

❯ uv run --with 'rich' .\test.py
For example: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:01

还可以限定使用特定版本的第三方库:

❯ uv run --with 'rich>12,<13' .\test.py
For example: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00

当然,这么做很麻烦,每次运行脚本都需要在命令行通过参数指定依赖,有一种更简单的方式。

假设我们要执行的脚本是:

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 add --script test2.py 'requests<3' 'rich'
Updated `test2.py`

查看 test2.py 脚本会发现,uv 在文件头部添加了特殊格式的注释:

# /// script
# requires-python = ">=3.13"
# dependencies = [
#     "requests<3",
#     "rich",
# ]
# ///

这个注释表明了脚本使用的第三方依赖。

此时再通过 uv 运行脚本:

❯ uv run test2.py

依然可以自动检测并安装第三方依赖,而且不需要通过命令行参数指定依赖。

但需要注意的是,这种方式只适用于单独的脚本文件,不要对 Python 项目中的 Python 文件使用。

项目开发

示例项目已上传 Github

创建项目

可以通过 uv 创建项目目录:

uv init hello-world

如果项目目录已经存在,可以使用uv init命令初始化当前目录为项目目录。

此时会生成一个项目骨架:

❯ cd .\hello-world\
❯ ls

    Directory: D:\workspace\learn-python\hello-world

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           2025/8/12    12:53            109 .gitignore
-a---           2025/8/12    12:53              5 .python-version
-a---           2025/8/12    12:53             89 main.py
-a---           2025/8/12    12:53            157 pyproject.toml
-a---           2025/8/12    12:53              0 README.md

.python-version文件记录了当前项目运行的 python 版本,这样 uv 在运行时就会以指定版本运行项目。

使用 uv 运行项目:

❯ uv run main.py
Using CPython 3.13.6
Creating virtual environment at: .venv
Hello from hello-world!

uv 会自动在项目目录下创建一个.venv目录作为虚拟环境的依赖包的安装目录。

依赖管理

项目中的依赖同样可以使用 uv 进行管理,如果要添加依赖:

uv add 'requests==2.31.0'
uv add rich

uv 会将相应的依赖安装到虚拟环境目录.venv中,并且在项目描述文件pyproject.toml中添加依赖信息:

dependencies = [
    "requests==2.31.0",
    "rich>=14.1.0",
]

如果要移除依赖:

uv remove requests

项目配置

通常我们创建的项目都希望以命令行或界面的方式启动,这需要在项目描述文件中添加相应的启动信息。

如果以命令行方式运行:

[project.scripts]
hello = "icexmoon__hello_world.__main__:main"

这里的项目结构类似:

icexmoon-hello-world/
├── src/
│   ├── icexmoon_hello_world/
│   │   ├── __main__.py    # 包含 main() 函数
├── pyproject.toml

版本管理

通常在发布前或发布后需要修改项目版本,通常是直接修改项目描述文件(pyproject.toml),但也可以通过 uv 命令进行修改:

❯ uv version 0.1.1
Resolved 10 packages in 489ms
Audited 9 packages in 0.03ms
hello-world 0.1.0 => 0.1.1

不带版本号是查看项目当前版本:

❯ uv version
hello-world 0.1.1

发布项目

使用 uv build命令可以创建(打包) python 项目的二进制发行版本(.whl文件):

❯ uv build

生成的文件保存在dist目录下。

发布项目:

❯ uv publish
Publishing 2 files https://upload.pypi.org/legacy/
Enter username ('__token__' if using a token): __token__
Enter password:
Uploading icexmoon_hello_world-0.1.1-py3-none-any.whl (1.5KiB)
Uploading icexmoon_hello_world-0.1.1.tar.gz (1.1KiB)

现在 pyp 使用 token 校验,用户名需要填写 __token__,密码填写你的 token。

如果报错,可能是项目重名导致,重新起一个不同的项目名再发布(需要重新打包)。

通过这种方式上传每次都需要输入用户名和密码(token),如果是私人电脑,可以使用 twine 发布项目,它支持通过环境变量设置用户名和密码,这样就不需要每次都重新输入:

python -m twine upload dist/* --skip-existing

安装项目

通过命令uv tool可以安装、更新项目,其用途类似于 pip。

比如安装已发布的项目:

uv tool install icexmoon-hello-world

更新已安装的项目:

uv tool upgrade icexmoon-hello-world

更新所有通过 uv 安装的项目:

uv tool upgrade --all

和安装 python 类似,安装的项目如果是命令行可执行的,会在用户/.local/bin目录下创建一个.exe文件,可以直接在命令行下执行:

❯ hello
Hello from hello-world!

pip install不同的是,通过uv tool install安装的包不会使其模块在当前环境可用,换言之通过这种方式安装的包之间是互相隔离的,比如:

❯ python3.13 -c "import icexmoon_hello_world"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
    import icexmoon_hello_world
ModuleNotFoundError: No module named 'icexmoon_hello_world'

The End.

参考资料

Logo

葡萄城是专业的软件开发技术和低代码平台提供商,聚焦软件开发技术,以“赋能开发者”为使命,致力于通过表格控件、低代码和BI等各类软件开发工具和服务

更多推荐