每次开始一个新的 Python 项目,写代码之前,总要先处理一遍环境:安装 Python、选择解释器、创建虚拟环境、安装依赖,再考虑怎么把这套环境交给别人复现。
这些事情并不复杂,但步骤分散,切换项目时也容易混乱。
最近用上 uv,我最直接的感受就是:速度快、使用方便、命令简单,搭建项目的过程顺畅了很多。
这篇文章整理了我使用 uv 的常用流程,从安装 uv,到管理 Python、创建项目、恢复依赖,再到 WSL 下的代理排查。新建项目时,可以直接照着操作。
本文命令以 WSL / Linux 为例。uv 会持续更新,具体参数可通过
uv help和官方文档确认。
一、安装 uv:一条命令开始
在 WSL 终端中执行:
bash
curl -LsSf https://astral.sh/uv/install.sh | sh
如果需要安装指定版本,例如 0.7.4,可以把版本号写进安装地址:
bash
curl -LsSf https://astral.sh/uv/0.7.4/install.sh | sh
两种方式选择一种即可。前者使用当前安装入口,后者指定 uv 自身的版本。0.7.4 仅作为指定版本的示例,不代表最新版本。安装方式见官方文档。
安装完成后,按照安装器提示刷新当前终端环境。默认安装位置通常可以这样加载:
bash
source "$HOME/.local/bin/env"
也可以重新打开终端。如果安装器已经更新了 Shell 配置,则根据自己使用的 Shell 加载对应文件:
bash
# Bash
source ~/.bashrc
# Zsh
source ~/.zshrc
选择与当前 Shell 对应的一条即可。
最后检查安装结果:
bash
uv --version
二、安装 Python,并指定项目使用的版本
uv 可以管理 Python 解释器。比如安装 Python 3.12:
bash
uv python install 3.12
查看本机已经安装的 Python:
bash
uv python list --only-installed
接下来,需要分清楚两件事:指定 uv 使用的 Python 版本,以及修改终端里 python 命令的指向。
如果希望 uv 在没有项目版本配置时默认选择 Python 3.12,可以设置全局版本偏好:
bash
uv python pin --global 3.12
如果只想固定当前项目使用的版本,在项目目录执行:
bash
uv python pin 3.12
这会生成或更新 .python-version 文件,内容类似:
text
3.12
项目中的版本配置优先于全局版本偏好。它影响 uv 如何选择解释器,并不等于直接替换系统 Python。Python 版本选择规则见官方文档。
如果还希望为 uv 管理的 Python 创建 python、python3 默认可执行入口,当前版本提供:
bash
uv python install 3.12 --default
实际在终端中调用哪个 Python,仍然取决于 PATH 的顺序,可以用下面的命令确认:
bash
command -v python
python --version
uv python pin 固定的是 Python 版本。 如果需要固定 uv 自身的版本,应在安装时指定版本号。相关参数见命令参考。
三、创建项目:从目录到虚拟环境
先初始化项目:
bash
uv init my_project
cd my_project
再指定 Python 版本,创建虚拟环境:
bash
uv python pin 3.12
uv venv --python 3.12
默认情况下,虚拟环境会创建在项目根目录下的 .venv 目录中。
如果习惯先激活环境,再运行 Python,可以执行:
bash
source .venv/bin/activate
确认解释器版本:
bash
python --version
退出虚拟环境:
bash
deactivate
uv 还有一种很方便的用法:直接通过 uv run 在项目环境中执行命令。
bash
uv run python --version
运行初始化生成的脚本:
bash
uv run python main.py
使用 uv run 时,可以省去手动激活环境这一步。它会在执行前检查项目依赖与环境状态,必要时创建环境并同步依赖。项目工作流见官方文档。
四、安装和移除依赖:记住 add 和 remove
以 OpenAI Python SDK 为例,添加依赖:
bash
uv add openai
这一步会同时更新项目依赖声明、锁文件和项目环境。
可以用一条命令检查包是否能够导入:
bash
uv run python -c "import openai; print(openai.__version__)"
不再需要时,移除依赖:
bash
uv remove openai
如果项目已经交给 uv 管理,日常增删依赖就优先使用 uv add 和 uv remove,让依赖记录与环境保持一致。依赖管理说明。
五、uv.lock 怎么恢复?一条 sync 同步环境
理解 uv 项目,可以先记住这几个文件的分工:
| 文件或目录 | 作用 | 通常是否提交到 Git |
|---|---|---|
pyproject.toml |
项目元信息和依赖声明 | 是 |
uv.lock |
解析后的具体依赖版本 | 是 |
.python-version |
项目使用的 Python 版本请求 | 是 |
.venv/ |
本机虚拟环境和已安装的包 | 否 |
换电脑或拉取项目后,在项目根目录执行:
bash
uv sync
uv 会根据项目配置和锁文件同步环境;如果 .venv 不存在,会自动创建。
如果希望严格使用已有锁文件,并在依赖声明与锁文件不一致时直接报错,可以使用:
bash
uv sync --locked
恢复环境时,不需要提前准备 .venv,也不要求它必须不存在。 已有环境可以直接同步,只有确认需要重建时,才考虑移走旧环境再重新创建。
还需要注意:uv sync 默认会移除当前同步目标之外的额外包。因此,项目长期需要的依赖应通过 uv add 记录下来。锁定与同步机制见官方文档。
六、已有 requirements.txt,也能继续用
遇到旧项目,不一定要立刻调整整套依赖管理方式。
先创建虚拟环境:
bash
uv venv --python 3.12
然后按照 requirements.txt 安装依赖:
bash
uv pip install -r requirements.txt
uv 的 pip 兼容接口能够发现当前目录下的 .venv,通常不需要先手动激活。环境发现规则见官方文档。
如果希望把已有依赖导入 uv 项目管理,可以在已有 pyproject.toml 的项目中执行:
bash
uv add -r requirements.txt
这样,依赖会进入项目声明,并生成或更新 uv.lock。迁移方式见官方指南。
导出依赖时,也有两种不同需求。
记录当前环境已经安装的包:
bash
uv pip freeze > requirements.txt
从 uv 项目的锁定依赖导出 requirements 格式:
bash
uv export --locked --format requirements.txt --output-file requirements.txt
前者读取当前环境,后者依据项目锁文件导出。使用 uv 管理的项目,通常选择后者,更容易与项目依赖记录保持一致。导出锁文件说明。
七、命令行工具,交给 uv tool
除了项目依赖,开发中还会用到一些独立的命令行工具,比如 Ruff。
如果只想临时运行一次:
bash
uvx ruff check .
uvx 是 uv tool run 的简写,因此也可以写成:
bash
uv tool run ruff check .
如果想把它安装成长期使用的命令:
bash
uv tool install ruff
查看和卸载工具:
bash
uv tool list
uv tool uninstall ruff
这些工具由 uv 放在独立环境中管理。如果某个工具需要随项目统一版本,也可以将其添加为开发依赖:
bash
uv add --dev ruff
uv run ruff check .
选择方式取决于用途:个人终端常用工具适合 uv tool,项目统一使用的工具适合记录在项目依赖中。工具管理说明。
八、WSL 下代理连接失败,按顺序排查
在 WSL 中安装包,有时会遇到连接超时、代理连接失败等问题。这时候,可以先确认代理配置是否正确。
1. 检查并设置代理变量
假设 Windows 上的代理服务可以通过 192.168.176.1:7890 访问,在 WSL 中设置:
bash
export HTTP_PROXY="http://192.168.176.1:7890"
export HTTPS_PROXY="http://192.168.176.1:7890"
这里的 IP 和端口都是示例,需要替换成自己的实际配置。
HTTPS_PROXY 的值写成 http://... 并不矛盾:它表示 HTTPS 请求通过这个 HTTP 代理入口连接。uv 支持读取 HTTP_PROXY、HTTPS_PROXY 和 ALL_PROXY 等环境变量。代理变量说明。
2. 确认 WSL 能访问 Windows 上的代理
WSL 与 Windows 之间如何连接,取决于当前网络模式。
在默认 NAT 模式下,访问 Windows 服务通常需要使用宿主机地址;镜像网络模式下,则可以通过 127.0.0.1 连接 Windows 服务。因此,其他机器上的代理地址不能直接照搬。WSL 网络说明。
还需要检查:
- 填写的是 HTTP 代理端口,还是 SOCKS 端口。
- 代理程序是否监听了 WSL 可以访问的地址。
- 使用宿主机 IP 连接时,代理程序是否允许相应连接。
- 防火墙是否放行了对应端口和来源。
可以先从 WSL 测试代理是否能访问包索引:
bash
curl -I --connect-timeout 10 \
--proxy http://192.168.176.1:7890 \
https://pypi.org/simple/
这一步成功后,再重试:
bash
uv sync -v
3. 不使用代理时,清理残留配置
如果代理已经关闭,但终端仍保留旧变量,也可能导致请求失败:
bash
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY http_proxy https_proxy all_proxy
这只会清理当前终端的变量。如果代理写进了 ~/.bashrc 或 ~/.zshrc,还需要修改对应配置。
排查时,先确认地址、端口、监听范围和代理变量;出现明确的域名解析异常时,再检查 DNS 覆写设置。防火墙则优先调整对应端口的访问规则。
九、下次新建项目,可以直接用这套流程
安装好 uv 后,新项目的常用流程可以压缩成:
bash
# 安装 Python
uv python install 3.12
# 初始化项目
uv init my_project
cd my_project
# 固定项目 Python 版本
uv python pin 3.12
# 添加依赖,自动准备项目环境
uv add openai
# 运行代码
uv run python main.py
其他人拿到包含 pyproject.toml、uv.lock 和 .python-version 的项目后,可以执行:
bash
uv sync --locked
uv run python main.py
这也是我喜欢 uv 的原因:常用命令短,步骤连贯,从创建项目到恢复环境,都有比较统一的操作方式。
这次使用下来,我最明显的感受还是快。这里没有做严格的性能测试,所以不写具体提升倍数;但在安装依赖、切换环境和启动新项目时,它确实让我少花了不少等待和整理环境的时间。
对经常写 Python 脚本、调用大模型 API,或者需要反复创建实验项目的人来说,环境搭建越顺手,就越容易把精力放回代码本身。