文章摘要
uv工具可以简化Python脚本的执行,自动管理脚本依赖的虚拟环境,无需手动配置。通过uv run命令,可以直接运行无依赖或仅依赖标准库的脚本,并支持传递参数。uv推荐使用声明式方法管理依赖,确保环境隔离和依赖管理的便捷性。
文章总结
使用 uv 运行 Python 脚本
Python 脚本是一个可以独立执行的文件,通常通过 python <script>.py 命令运行。使用 uv 工具来执行脚本可以自动管理脚本的依赖,而无需手动配置环境。
运行无依赖的脚本
如果脚本没有依赖,可以直接使用 uv run 命令执行:
bash
$ uv run example.py
如果脚本依赖于标准库中的模块,也无需额外操作:
bash
$ uv run example.py
可以通过命令行参数传递参数给脚本:
bash
$ uv run example.py test
还可以通过标准输入直接读取脚本内容:
bash
$ echo 'print("hello world!")' | uv run -
如果在项目中运行脚本(即目录中包含 pyproject.toml 文件),uv run 会先安装项目依赖。如果脚本不依赖项目,可以使用 --no-project 标志跳过此步骤。
运行有依赖的脚本
当脚本需要其他包时,这些包必须安装在脚本运行的环境中。uv 倾向于按需创建这些环境,而不是使用长期存在的虚拟环境。可以通过 --with 选项指定依赖:
bash
$ uv run --with rich example.py
如果需要特定版本的依赖,可以添加约束条件:
bash
$ uv run --with 'rich>12,<13' example.py
多个依赖可以通过重复 --with 选项来指定。
创建 Python 脚本
Python 最近引入了内联脚本元数据的标准格式,允许选择 Python 版本并定义依赖。可以使用 uv init --script 初始化带有内联元数据的脚本:
bash
$ uv init --script example.py --python 3.12
声明脚本依赖
内联元数据格式允许在脚本中声明依赖。使用 uv add --script 可以为脚本声明依赖:
bash
$ uv add --script example.py 'requests<3' 'rich'
这将在脚本顶部添加一个 script 部分,使用 TOML 格式声明依赖。
使用 shebang 创建可执行文件
可以通过添加 shebang 使脚本无需使用 uv run 即可执行:
```bash
!/usr/bin/env -S uv run --script
```
确保脚本具有可执行权限后,可以直接运行:
bash
$ ./greet
使用替代包索引
如果需要使用替代包索引来解析依赖,可以通过 --index 选项指定:
bash
$ uv add --index "https://example.com/simple" --script example.py 'requests<3' 'rich'
锁定依赖
uv 支持使用 uv.lock 文件格式锁定 PEP 723 脚本的依赖。使用 uv lock 可以显式锁定依赖:
bash
$ uv lock --script example.py
提高可重复性
除了锁定依赖,uv 还支持在内联脚本元数据的 tool.uv 部分中添加 exclude-newer 字段,以限制仅考虑在特定日期之前发布的包。
使用不同的 Python 版本
uv 允许在每次脚本调用时请求不同的 Python 版本:
bash
$ uv run --python 3.10 example.py
使用 GUI 脚本
在 Windows 上,uv 会使用 pythonw 运行以 .pyw 结尾的脚本。
下一步
评论总结
评论主要围绕 uv 工具及其对 Python 脚本依赖管理的支持展开,观点多样,既有积极评价,也有批评和建议。
积极评价:
uv的脚本依赖管理功能受到高度赞扬:- gopalv 表示这是其最喜欢的
uv功能,并因此切换到uv,因为它允许在不创建虚拟环境的情况下使用依赖项。 > "This is my absolute favourite uv features and the reason I switched to uv." - simonw 认为声明脚本依赖的功能非常有用,特别是通过
uv run script.py可以自动安装依赖并运行脚本。 > "The 'declaring script dependencies' thing is incredibly useful."
- gopalv 表示这是其最喜欢的
uv的易用性和创新性:- m4r71n 提到
uv lock --script example.py命令为单个脚本创建锁文件的功能非常自然且创新。 > "Amazing how this feels so natural and yet only appeared after 20+ years of Python packaging." - trostaft 认为
uv简化了学生运行 Python 代码的过程,只需一条命令即可。 > "Now, I can just tell them to get uv (single command) and run it."
- m4r71n 提到
批评与建议:
对
pip不支持 PEP 723 的质疑:- satertek 质疑为什么
pip不支持 PEP 723,认为应该有官方实现。 > "Why doesn't pip support PEP 723?"
- satertek 质疑为什么
uv的局限性:- AceJohnny2 指出
uv仅适用于单文件脚本,多文件项目仍需使用pyproject.toml。 > "Note that this only works for single-file scripts." - hoherd 提醒在无网络环境下使用
uv可能导致脚本失败,建议预先安装依赖。 > "Don't use this for code that may need to run airgapped!"
- AceJohnny2 指出
文档不足的批评:
- imcritic 批评文档不够详细,特别是关于依赖版本管理和缓存机制的部分。 > "I hate such poor docs that don't explain how things work."
其他观点:
uv在 Jupyter 中的应用:- heisenzombie 分享了一个基于
uv的 Jupyter 内核项目,并提到正在开发的相关插件。 > "It’s a pretty minimal wrapper around 'uv' and 'iPython' to provide the functionality from the article, but for Jupyter notebooks."
- heisenzombie 分享了一个基于
对 Python 包管理复杂性的抱怨:
- rr808 对 Python 包管理工具的多样性表示不满,质疑是否需要这么多工具。 > "How many package managers can one language have?"
总结:uv 的脚本依赖管理功能受到广泛好评,特别是在简化依赖管理和运行脚本方面。然而,其局限性、文档不足以及对 pip 的质疑也引发了一些讨论。此外,uv 在 Jupyter 中的应用和 Python 包管理工具的复杂性也是评论中的热点话题。