Post

Python小记

Python小记

uv-包与环境管理工具

版本管理

  • uv python install ~:安装 Python 版本。
  • uv python list:查看可用的 Python 版本。
  • uv python find ~:查找已安装的 Python 版本。
  • uv python pin ~:为当前项目指定使用的 Python 版本。
  • uv python default ~:指定全局 Python 版本。
  • uv python uninstall ~:卸载 Python 版本。

环境与包管理

环境

1
2
3
4
5
6
7
8
# 创建名为 .venv 的虚拟环境(默认)
uv venv

# 激活环境(macOS/Linux)
source .venv/bin/activate

# 激活环境(Windows)
.venv\Scripts\activate

包管理

1
2
3
4
5
6
7
8
# 安装最新版本
uv pip install requests

# 安装特定版本
uv pip install requests==2.31.0

# 从 requirements.txt 安装
uv pip install -r requirements.txt

安装包到开发环境:

uv pip install \--dev pytest

升级包:

uv pip upgrade requests

卸载包:

uv pip uninstall requests

导出依赖:

1
2
3
4
5
# 导出当前环境的依赖
uv pip freeze > requirements.txt

# 导出生产环境依赖(排除开发依赖)
uv pip freeze --production > requirements.txt

项目管理

  • 初始化新项目 uv init my_project
  • 依赖 基本的项目结构和 pyproject.toml 文件
  • 安装项目依赖 uv sync
    • 根据 pyproject.toml 和 requirements.txt 安装所有依赖

conda迁移uv

导出conda环境的包清单

1
2
3
4
# 先激活你的 conda 环境
conda activate your_env_name
# 导出清单
conda list --export > requirements.txt

方案1-混合使用

  • conda创建空环境:conda create --name new\_env python=3.10
  • 激活环境:conda activate new_env
  • 使用uv安装包:uv pip install -r requirements.txt

方案2-仅使用uv

  • 创建新的虚拟环境 uv venv
  • 激活环境
    • 在 Windows 上 (Powershell): .venv\Scripts\Activate.ps1
    • 在 macOS / Linux 上: source .venv/bin/activate
  • 安装包 uv pip install -r requirements.txt

其它迁移到uv

pip + virtualenv 项目

1
2
3
4
5
6
# 创建并激活 uv 虚拟环境
uv venv
source .venv/bin/activate

# 安装依赖
uv pip install -r requirements.txt

pip-tools 项目

1
2
uv pip compile requirements.in -o requirements.txt
uv pip sync

poetry 或 pdm 项目

1
2
# 直接使用现有的 pyproject.toml
uv sync

运行脚本

注意: 在项目中使用 uv -run,即在包含 pyproject.toml 的目录中,会在运行前自动安装当前项目,可以使用 --no-project 标志跳过此步骤。
使用示例:

1
2
# 注意,标志必须在脚本之前
uv run --no-project example.py

直接运行

无依赖的情况
  • 运行脚本文件 uv run example.py [传递参数]
  • stdin读取脚本 echo 'print("hello world!")' | uv run -
  • here-documents:
    1
    2
    3
    
    uv run - <<EOF
    print("hello world!")
    EOF
    
有依赖的情况
  • uv run --with 'rich>12,<13' example.py
  • uv run --with rich example.py
  • 可重复使用 --with 添加多个依赖

内联脚本

  • 指定python版本uv init --script example.py --python 3.12
  • 声明依赖uv add --script example.py 'requests<3' 'rich'

这将会在脚本顶部添加一个 script 部分,使用 TOML 声明依赖项:

1
2
3
4
5
6
7
8
9
10
11
12
13
# /// 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])

运行时会自动创建环境,安装相关的依赖项

  • 指定在特定日期之前的发布版本 tool.uv 中的 exclude-newer字段
1
2
3
4
5
6
7
8
9
10
11
# /// script
# dependencies = [
#   "requests",
# ]
# [tool.uv]
# exclude-newer = "2023-10-16T00:00:00Z"
# ///

import requests

print(requests.__version__)

指定运行的python版本

uv run --python 3.10 example.py

GUI脚本

在 Windows 上,uv 会使用 pythonw 运行以 .pyw 扩展名结尾的脚本:

1
2
3
4
5
6
7
8
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()

同样,它也适用于带有依赖项的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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_())

PS> uv run --with PyQt5 example_pyqt.pyw

工具

常识和工具路径

由于不安装工具而运行它们非常常见,因此提供了 uvx 别名来代替 uv tool run —— 这两个命令完全等效。

当使用 uvx 运行工具时,虚拟环境会存储在 uv 缓存目录中,并被视为一次性环境,即,如果你运行 uv cache clean,该环境将会被删除。该环境仅被缓存,以减少重复调用的开销。如果环境被删除,将会自动创建一个新的环境。

当使用 uv tool install 安装工具时,虚拟环境会被创建在 uv tools 目录中。除非工具被卸载,否则该环境不会被删除。如果环境被手动删除,工具将无法运行。

工具目录:默认情况下,uv 工具目录名为 tools,并位于 uv 应用状态目录中,例如 ~/.local/share/uv/tools。该位置可以通过 UV_TOOL_DIR 环境变量进行自定义。

要显示工具安装目录的路径,可以使用以下命令:

uv tool dir
工具环境会被放置在与工具包名称相同的目录中,例如 .../tools/<name>

参考资料

This post is licensed under CC BY 4.0 by the author.