运行脚本
Python脚本是一种用于独立执行的文件,例如使用python
运行无依赖项的脚本
如果你的脚本没有依赖项,可以使用uv run来执行它:
同样地,如果你的脚本依赖于标准库中的模块,就无需额外操作:
可以向脚本提供参数:
此外,你的脚本可以直接从标准输入读取:
或者,如果你的 shell 支持 here-documents:
请注意,如果在项目目录(即包含pyproject.toml文件的目录)中使用uv run命令,它会在运行脚本前先安装当前项目。如果您的脚本不依赖该项目,可以使用--no-project标志跳过此步骤:
$ # Note: the `--no-project` flag must be provided _before_ the script name.
$ uv run --no-project example.py
查看项目指南获取更多关于项目工作的详细信息。
运行带依赖项的脚本
当您的脚本需要其他软件包时,这些包必须安装在脚本运行的环境中。uv倾向于按需创建这些环境,而不是使用需要手动管理依赖项的长期存在的虚拟环境。这需要明确声明脚本所需的依赖项。通常建议使用项目或内联元数据来声明依赖关系,但uv也支持每次调用时请求依赖项。
例如,以下脚本需要 rich。
import time
from rich.progress import track
for i in track(range(20), description="For example:"):
time.sleep(0.05)
如果不指定依赖项就执行,此脚本将失败:
$ uv run --no-project example.py
Traceback (most recent call last):
File "/Users/astral/example.py", line 2, in <module>
from rich.progress import track
ModuleNotFoundError: No module named 'rich'
使用--with选项请求依赖项:
如果需要特定版本,可以向请求的依赖项添加约束:
可以通过重复使用--with选项来请求多个依赖项。
请注意,如果在项目中使用uv run命令,这些依赖项将会额外包含在项目依赖项中。若要禁用此行为,请使用--no-project标志。
创建Python脚本
Python 最近新增了内联脚本元数据的标准格式。它允许选择 Python 版本并定义依赖项。使用 uv init --script 命令来初始化带有内联元数据的脚本:
声明脚本依赖项
内联元数据格式允许在脚本本身中声明其依赖项。
uv支持为您添加和更新内联脚本的元数据。使用uv add --script来声明脚本的依赖项:
这将在脚本顶部添加一个script部分,使用TOML格式声明依赖项:
# /// script
# 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会自动创建一个包含运行脚本所需依赖项的环境,例如:
$ uv run example.py
[
│ ('1', 'PEP Purpose and Guidelines'),
│ ('2', 'Procedure for Adding New Modules'),
│ ('3', 'Guidelines for Handling Bug Reports'),
│ ('4', 'Deprecation of Standard Modules'),
│ ('5', 'Guidelines for Language Evolution'),
│ ('6', 'Bug Fix Releases'),
│ ('7', 'Style Guide for C Code'),
│ ('8', 'Style Guide for Python Code'),
│ ('9', 'Sample Plaintext PEP Template'),
│ ('10', 'Voting Guidelines')
]
重要
使用内联脚本元数据时,即使在项目中使用了uv run,项目的依赖项也会被忽略。此时不需要使用--no-project标志。
uv 也遵循 Python 版本要求:
# /// script
# requires-python = ">=3.12"
# dependencies = []
# ///
# Use some syntax added in Python 3.12
type Point = tuple[float, float]
print(Point)
注意
即使为空,也必须提供dependencies字段。
uv run 会自动查找并使用所需的Python版本。如果该Python版本未安装,将会自动下载——更多详情请参阅Python版本文档。
使用shebang创建可执行文件
可以添加 shebang 来使脚本无需使用 uv run 即可执行——这样可以轻松运行位于你的 PATH 或当前文件夹中的脚本。
例如,创建一个名为greet的文件,内容如下
确保您的脚本可执行,例如使用chmod +x greet,然后运行脚本:
在此上下文中也支持依赖项的声明,例如:
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = ["httpx"]
# ///
import httpx
print(httpx.get("https://example.com"))
使用替代包索引
如果你想使用其他包索引来解析依赖项,可以通过--index选项提供索引:
这将在内联元数据中包含包数据:
如果您需要身份验证才能访问包索引,请参阅package index文档。
锁定依赖项
uv支持使用uv.lock文件格式锁定PEP 723脚本的依赖项。与项目不同,脚本必须使用uv lock明确锁定:
运行uv lock --script会在脚本旁边创建一个.lock文件(例如example.py.lock)。
一旦锁定,后续操作如uv run --script、uv add --script、uv export --script和uv tree --script将复用已锁定的依赖项,必要时会更新锁文件。
如果不存在这样的锁定文件,像uv export --script这样的命令仍会按预期工作,
但不会创建锁定文件。
提升可复现性
除了锁定依赖项外,uv还支持在内联脚本元数据的tool.uv部分中使用exclude-newer字段,以限制uv仅考虑在特定日期之前发布的发行版。这对于提高脚本在将来运行时重现性非常有用。
日期必须指定为RFC 3339时间戳格式
(例如:2006-12-02T02:07:43Z)。
# /// script
# dependencies = [
# "requests",
# ]
# [tool.uv]
# exclude-newer = "2023-10-16T00:00:00Z"
# ///
import requests
print(requests.__version__)
使用不同的Python版本
uv允许在每次脚本调用时请求任意的Python版本,例如:
查看Python版本请求文档 获取关于请求Python版本的更多详细信息。
使用图形界面脚本
在Windows上,uv会使用pythonw运行以.pyw扩展名结尾的脚本:
from tkinter import Tk, ttk
root = 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()

同样地,它也适用于依赖项:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QGridLayout
app = QApplication(sys.argv)
widget = QWidget()
grid = QGridLayout()
text_label = QLabel()
text_label.setText("Hello World!")
grid.addWidget(text_label)
widget.setLayout(grid)
widget.setGeometry(100, 100, 200, 50)
widget.setWindowTitle("uv")
widget.show()
sys.exit(app.exec_())

下一步
要了解更多关于uv run的信息,请参阅命令参考。
或者,继续阅读了解如何通过uv运行和安装工具。