UV学习笔记:闪电级Python包管理
最近在学习MCP时接触到了uv这个工具,感觉它既强大,又好用,于是整理了一期uv使用视频教程,已在视频号「退役程序员」中发布,这次我将学习中总结的笔记一并分享,供大家参考。
💠 UV基础
🔘 什么是UV
uv是一个现代的Python包安装器和解析器,旨在成为pip和pip-tools的快速替代品,提供更快的依赖解析和安装速度,并支持灵活的依赖管理。uv的目标是解决Python生态系统中长期存在的依赖管理痛点,例如速度慢、依赖冲突难以解决等问题。
### 🔘 安装UV
具体安装方式请参考其官网说明:
https://docs.astral.sh/uv/getting-started/installation/
本机上我用的是:
brew install uv
查看可用的参数和说明文档,安装后在命令行输入:
uv
🔘 安装不同版本的python
查看可安装和已安装的python列表:
uv python list
安装某个版本的Python
uv python install 3.12
查找路径
uv python find 3.12
卸载
uv python uninstall 3.12
💠 在没有设置持久虚拟环境时使用uv
🔘 运行代码
我有一个简单的main.py文件来打印正在使用的Python版本和路径:
import sys
print(sys.version)
print(sys.executable)用uv来运行它,可以输入以下命令:
uv run main.py
🔘 选择特定python版本运行
uv run --python 3.11 main.py
🔘 确保依赖库可用
如果我的代码中引入了如requests这样的外部库,例如:
import sys
import requests
print(sys.version)
print(sys.executable)如何来确保依赖库可用呢?这里有三种方法:
方法1:
命令行中添加--with requests
运行下面的命令:
uv run --with requests --python 3.11 main.py
方法2:
内联脚本元数据中修改dependencies = []
先用下列命令为main.py加入内联脚本元数据代码:
uv init --script main.py --python 3.12
这会自动在代码前加入内联脚本元数据:
# /// script
# requires-python = ">=3.12"
# dependencies = []
# ///
import sys
import requests
print(sys.version)
print(sys.executable)# /// script 和
# ///之间的内容被称为内联脚本元数据,它允许将脚本的元数据(例如本例中所需的Python版本和依赖)直接嵌入到脚本文件的顶部。这部分脚本告诉uv如何在后台正确地准备和运行main.py所需的Python环境和依赖。
如果还没有main.py文件,则会自动生成一个main.py文件:
# /// script
# requires-python = ">=3.12"
# dependencies = []
# ///
def main() -> None:
print("Hello from main.py!")
if __name__ == "__main__":
main()在其中手动修改# dependencies = [],变为:
# dependencies = ["requests"]
方法3 使用uv add命令
本例中,可以直接使用下面命令添加:
uv add --script main.py "requests"
请注意,这时我们并没有创建一个持久的虚拟环境来运行程序,这时的uv会为main.py动态地创建一个临时的、隔离的虚拟环境。它是临时的按需创建,uv
会智能地缓存这个环境,只要脚本的依赖或Python版本没有改变,就会在后续运行同一个脚本时复用它。
💠持久虚拟环境下的Python项目
🔘 创建项目目录
创建一个名为newproject的新项目(如在本课对应视频课程中),可输入如下命令:
uv init newproject
这会直接创建一个名为newproject的项目目录
或者,也可以在一个已存在的目录中输入uv init来创建(默认创建的项目是个应用,省略参数–app)
1.
pyproject.toml
这是Python项目的核心配置文件,uv也会使用它来识别该项目的根目录。
项目初始化后的toml文件内容一般是这样的:
[project]
name = "projectname"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = []
name: 该项目名称。这对于标识项目至关重要,尤其是在发布包时。version: 该项目当前版本。这有助于跟踪更改和发布。description: 该项目功能的简短摘要。readme: 指定该项目 README 文件的路径。requires-python: 指定该项目兼容的 Python 版本。uv在创建环境或安装依赖项时会遵守这一点。dependencies: 项目运行所需的直接依赖项列表。这些通常指定为包名,可带有版本约束。uv将使用它来解析和安装该项目的依赖。
2.
.python-version
用于指定项目使用的 Python 版本。
告诉uv在创建项目虚拟环境时应该使用哪个Python版本。这确保了项目的Python环境一致性。
3. .venv目录
这是一个隐藏目录,包含了项目虚拟环境。这是一个与系统其他Python环境隔离的独立Python环境。uv会将本项目依赖包安装到这个目录中。这种隔离有助于避免不同项目之间的依赖冲突,并确保项目在不同机器上运行的一致性。
4. README.md
这是一个Markdown格式的文本文件,通常用于项目的说明。提供项目的简介、安装说明、使用指南、贡献方式等信息。
5. .gitignore
这是一个文本文件,用于指定Git在版本控制中应该忽略的文件和目录。告诉Git哪些文件或目录不应该被提交到版本库中,例如虚拟环境
(.venv目录)、编译生成的文件、临时文件、敏感信息等。这有助于保持代码仓库的整洁。
6.
main.py或项目同名.py文件 (可选)
根据uv init的具体选项(例如 --app 或
--package)生成。
7.
uv.lock (在首次运行 uv add 或
uv sync 后生成)
这个文件不会在uv init时立即生成,而是在你首次添加依赖
(uv add) 或同步环境 (uv sync)
时创建。uv.lock
是一个锁文件,它记录了项目中所有依赖包(包括直接依赖和间接依赖)的精确版本。这个文件确保了项目在不同机器和不同时间上的可复现性。它应该被提交到版本控制中,以保证团队成员和部署环境都使用一致的依赖版本。
🔘 添加依赖库
在项目目录下,也可以像前面方法3中提到过的uv add命令添加:
uv add requests
如果此时项目目录中还没有创建虚拟环境,运行后虚拟环境会自动建立起来。(或者在项目目录中用uv venv命令来生成)
也可以在toml文件的dependencies = []中手动添加依赖的库,之后再运行:
uv run main.py
系统会自动运行un sync来同步(这个命令也可以输入命令行运行),
它也会自动生成uv.lock文件(或者用命令uv lock来生成) ### 🔘
卸载依赖库
如果要删除项目的依赖库requests,可以:
uv remove requests
🔘 修改Python版本
在安装依赖库时有时可能需要更低版本号的Python,这是需要降低项目Python环境的版本,可在toml文件中修改requires-python的值,例如requires-python = ">=3.8,<3.11",这时要确保uv环境中已经安装过较低版本的Python,可用命令uv python list来确认是否已安装。
🔘 显示项目依赖结构
uv tree
🔘 查看安装了哪些包
uv pip list
🔘 迁移旧有项目
如果是一个旧方法创建的项目文件夹,可利用requirements.txt将其变成uv环境:
uv add -r requirements.txt