几年前我在 Windows 11 上建一个 Python 项目,流程大概是:官网下载解释器、手动勾 PATH、python -m venv .venv、再 pip install 一堆依赖。后来接触到 uv,发现这个来自 Astral 的工具把 Python 管理、虚拟环境、依赖安装、锁定版本全串成了一条命令,而且是 Rust 写的,速度比 pip 快一个量级。这篇文章我会从 Windows 11 用户的视角,把安装、更新、Python 版本管理、环境切换和常见报错完整捋一遍,适合刚从 pip/conda 迁移过来,或者第一次接触 uv 的开发者。
1. 为什么我建议你在 Windows 11 上把 pip/conda 的备用节奏换成 uv
先说个反直觉的事:uv 刚发布时大家管它叫“极速 pip”,但实际用下来,它更像一个 Python 项目工作流工具。在 Windows 上,它把以往需要四五个工具拼起来的活压缩成了一个二进制。
1.1 uv 到底替掉了哪几个工具
如果你之前用过 pyenv-win、virtualenv、pip、pip-tools、Poetry 这类组合,那 uv 的操作界面会让你觉得熟悉,但它内部是一套全新设计。
uv python install替代 pyenv-win 的 Python 版本下载与切换。uv venv替代python -m venv和 virtualenv。uv add替代pip install+ 手动写 requirements。uv lock和uv sync替代 pip-tools 的编译与同步。uv run自动激活虚拟环境并运行脚本,替代“先 activate 再执行”的旧习惯。
它不是某个工具的简单复刻,而是把“项目即环境”这个思路做成了一套默认规则。每个项目目录里有 pyproject.toml、uv.lock、.venv,克隆下来就能跑。
1.2 Windows 上老环境管理方式的三个痛点
在 Windows 上,老流程有三个最折磨人的地方。
第一个是 Python 版本切换。官网安装包装多个版本后,PATH 里容易互相覆盖,pyenv-win 虽然能用,但要额外装一堆依赖,偶尔还会出现编译工具链问题,新手很容易卡住。
第二个是虚拟环境激活。每次进项目都要记得 activate,忘了就装错环境。PowerShell 还会因为执行策略禁止运行 Activate.ps1,需要先修改策略,这个坑我踩过不止一次。
第三个是依赖解析慢。pip 默认走简单解析,遇到版本冲突不会自动回溯,经常要手动锁定版本,或者靠 pip-tools 多跑一遍编译。uv 用的是类 PubGrub 解析器,碰到冲突会直接告诉你哪两个包互相打架,而不是装到一半才报错。
1.3 开始之前先理解 uv 的工作方式
uv 的核心理念可以总结成一句话:项目目录就是工作单元。
在项目里执行 uv add requests,它会自动创建 .venv、更新 pyproject.toml、生成 uv.lock。在别的机器或另一台 Windows 11 上,只要把这个项目目录拷过去,执行 uv sync,就能得到完全一致的环境。这个“一致性”才是它比 pip 组合拳强的更关键的点。
所以下面所有操作都会围绕这个理念展开。安装好 uv 之后,你不再需要关心“这个项目用系统 Python 还是虚拟环境 Python”,uv 会帮你决定。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 三分钟装好 uv:官方脚本、winget、scoop 三条路
Windows 11 上装 uv 的方法很多,我重点推荐三条路,按你的使用习惯选一条就行。
2.1 官方 PowerShell 脚本安装
打开 Windows Terminal,进入 PowerShell,执行:
powershell复制irm https://astral.sh/uv/install.ps1 | iex
irm 是 Invoke-RestMethod,iex 是 Invoke-Expression。意思是把官网脚本拉下来,在内存里直接执行。脚本会下载 uv 和 uvx 两个可执行文件,默认放到:
code复制C:\Users\<你的用户名>\.local\bin
安装完成后,它会提示你重启终端,或者手动把 .local\bin 加入 PATH。
这条命令的好处是版本新、安装快、不依赖系统里已有的 Python,它自己带一个独立二进制。
2.2 官方脚本被拦截时怎么办
在 Windows 11 上直接跑 irm | iex,有概率碰到这个报错:
code复制无法加载文件 ...,因为在此系统上禁止运行脚本。
原因很简单:默认执行策略是 Restricted,不允许执行任何 .ps1 脚本。虽然这里是把内容 pipe 给 iex,但策略仍然会拦。
解决办法是先放开当前用户的策略,再重试:
powershell复制Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
如果不想改系统策略,也可以在用 powershell 启动时临时绕过:
powershell复制powershell -ExecutionPolicy Bypass -c "irm https://astral.sh/uv/install.ps1 | iex"
两者选一个。前者会让以后激活虚拟环境也顺畅一些,因为我后面要用的 Activate.ps1 同样受这个策略影响。
2.3 用 winget 或 scoop 避开脚本问题
不想碰执行策略的话,用 winget 更省事。Windows 11 自带 winget,直接执行:
powershell复制winget install --id=astral-sh.uv -e
装完同样会放到 .local\bin。之后更新可以用:
powershell复制winget upgrade astral-sh.uv
如果你已经装了 Scoop,那就更简单:
powershell复制scoop install uv
Scoop 会把 uv 放到 shim 目录,PATH 由 Scoop 自己管理,基本不会有找不到命令的问题。
2.4 安装后确认:版本号与 PATH
装完后新开一个终端,执行:
powershell复制uv --version
如果输出类似:
code复制uv 0.7.x (Rust 1.x)
说明装好了。如果提示“无法将‘uv’项识别为 cmdlet、函数、脚本文件”,那就是 PATH 问题,我会在第 7 章详细说。
还可以顺手看一下 uvx 是否可用:
powershell复制uvx --version
uvx 是 uv 自带的“运行一次性工具”命令,很多场景会用到。
3. 第一次实操:uv init/add/remove/sync 与锁文件机制
装好之后,建议用一个空目录先跑一遍完整流程。这个流程会把“项目依赖管理”从“手动维护”升级成“自动声明”。
3.1 用 uv init 初始化项目
假设我要在 D:\projects 下建一个叫 demo-api 的项目:
powershell复制cd D:\projects
uv init demo-api
cd demo-api
执行完,目录里会生成这些文件:
code复制demo-api/
├── .python-version
├── .gitignore
├── README.md
├── pyproject.toml
├── main.py
└── uv.lock
pyproject.toml 是这个项目的声明文件,依赖、Python 版本要求、构建信息都在里面。.python-version 记录当前项目使用的 Python 版本。如果此时还没执行任何安装命令,uv.lock 可能是在初始化时就生成的空锁文件,不用感到奇怪。
想指定初始 Python 版本,可以加参数:
powershell复制uv init demo-api --python 3.12
这样项目会固定使用 Python 3.12。
3.2 添加和移除依赖
项目里执行:
powershell复制uv add requests
观察输出,uv 会做三件事:
- 创建或复用
.venv虚拟环境。 - 解析
requests及所有依赖的兼容版本。 - 把依赖写入
pyproject.toml的dependencies列表,并更新uv.lock。
如果想加开发环境才用的依赖,比如 pytest:
powershell复制uv add --dev pytest
新版 uv 会把这个写进 [dependency-groups] dev,这是当前 Python 社区推荐的开发依赖声明方式,和旧版的 dev-dependencies 不一样。
移除依赖直接用:
powershell复制uv remove pytest
它会同步更新 pyproject.toml 和 uv.lock,并且把 .venv 里对应的包卸载。
3.3 uv.lock 为什么值得当成宝贝
很多人第一次看 uv.lock 会疑惑:依赖不是已经写在 pyproject.toml 里了吗?为什么还要一个锁文件?
区别在于 pyproject.toml 写的是“宽泛要求”,比如 requests>=2.32.0。而 uv.lock 记录的是“实际锁定版本”,包括每个子依赖的具体版本、来源、哈希值。这让环境复现变得可靠。
换一台机器,把项目目录拷过去,执行:
powershell复制uv sync
它会严格按照 uv.lock 里锁定的版本安装环境,而不是根据 pyproject.toml 再解析一遍。这样就不会出现“在我电脑上能跑,在你电脑上报错”的问题。
uv sync 还有两个常用变体:
powershell复制uv sync --dev
uv sync --frozen
--dev 连开发依赖一起装,--frozen 表示不更新 lock 文件,只用当前锁文件同步环境,适合 CI 场景。
4. Python 版本管理:像切换 Node 版本一样管理解释器
过去在 Windows 上多版本 Python 并存一直很麻烦。uv 把 Python 下载、安装、版本切换集成了进去,体验有点像前端生态里的 nvm,但更简单。
4.1 uv python install:下载 Python 解释器
不用再去 python.org 下载安装包手动点下一步,直接在终端执行:
powershell复制uv python install 3.12
它会下载官方构建的 CPython 解释器,放到 uv 管理的目录,不需要管理员权限,也不会污染系统 PATH。想装 3.11 或 3.13 同理:
powershell复制uv python install 3.11
uv python install 3.13
也可以指定精确小版本:
powershell复制uv python install 3.11.9
如果想看看所有可用版本,执行:
powershell复制uv python list
它会同时列出已安装的版本和可下载的版本。只想看本地已经装了的:
powershell复制uv python list --only-installed
在 Windows 11 上,这些 Python 会被放到一个局部目录里,打开资源管理器也看不到常见的 C:\Python312 之类文件夹,但 uv 知道自己把它们放在哪,不需要你关心。
4.2 uv python pin:把项目固定到指定版本
光安装还不够,每个项目需要固定解释器版本。在项目根目录执行:
powershell复制uv python pin 3.12
这会在当前目录生成或更新 .python-version,文件内容可能就是一个简短的 3.12。这个文件跟着项目走,提交到 Git 里,团队成员拉下来后,uv sync 会自动使用这个 Python 版本。
如果项目里还没有这个版本的 Python,uv sync 会自动下载,不用单独手动执行 uv python install。
所以日常流程通常是:
powershell复制cd 某个项目
uv python pin 3.12
然后 uv 就默默把环境准备好了。
4.3 系统 Python 和 uv 托管 Python 怎么选
刚接触 uv 的人经常会问:我系统里装了一个 Python 3.12,uv 还会自己下载吗?
默认情况下,如果项目没有指定 Python 版本,uv 会优先查找系统已有的可用解释器;如果没找到,就会下载它管理的 Python。但你用 uv python pin 3.12 显式声明后,uv 会优先使用自己下载的托管版本,因为这样可以保证版本精确可控。
如果你希望尽量不下载 Python,始终使用系统解释器,可以设置环境变量:
powershell复制$env:UV_PYTHON_DOWNLOADS = "never"
这个变量会让 uv 禁止自动下载 Python,只使用系统已安装的解释器。写到这里我必须提醒一句:Windows 上系统 PATH 里的 Python 来源比较复杂,可能是官网装的,也可能是 Microsoft Store 装的,两者行为有差异。如果你的 python 命令指向的是 Microsoft Store 的启动器,最好在 uv 里用托管 Python,后面会少很多麻烦。
5. 环境切换:uv venv 与 uv run 的组合玩法
环境切换是 Windows 上最容易被忽略的痛点。uv 的设计会让你从“手动切换环境”切换到“自动识别项目环境”。
5.1 自动创建虚拟环境
在项目里首次执行 uv add 或 uv sync 时,uv 会自动创建 .venv。这个目录和传统 python -m venv .venv 创建的结构基本相同,区别在于它和依赖锁定是一套流程。
如果你想手动创建一个干净的虚拟环境,不初始化项目,也可以:
powershell复制uv venv
它会用当前目录或系统解释器创建 .venv。想指定 Python 版本:
powershell复制uv venv --python 3.12
创建完之后,正常的激活方式也支持:
powershell复制.venv\Scripts\Activate.ps1
但更推荐用 uv run,不需要手动激活。
5.2 uv run:不激活也能跑在正确环境里
在项目根目录执行:
powershell复制uv run python main.py
uv 会做这几件事:
- 检查
.venv是否存在,不存在则创建。 - 检查项目依赖是否和
pyproject.toml、uv.lock一致。 - 在
.venv中执行python main.py。
这就意味着你再也不用担心“是不是忘记 activate”了。哪怕你开了十个项目终端,每个项目根目录都不同,uv run 也能各自找到对应的环境。
如果想运行项目里安装的单独命令,比如 uv run pytest、uv run ruff check .,也可以直接执行。
如果想让 uv 在当前激活的虚拟环境中运行,而不是项目自动管理的 .venv,可以加:
powershell复制uv run --active python main.py
这个选项在极少见的情况下有用,日常建议默认用不带 --active 的命令。
5.3 手动激活与退出:什么时候真的需要
既然 uv run 能自动跑,那手动激活还有没有意义?
有。比如你要开发调试一个 Jupyter Notebook,或者用 IDE 里的终端长时间写代码,不希望每次命令都带 uv run 前缀。这时可以激活环境:
powershell复制.venv\Scripts\Activate.ps1
退出不叫 exit,而是:
powershell复制deactivate
在 PowerShell 里激活脚本如果也被执行策略拦住,和之前安装 uv 时一样,先执行:
powershell复制Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
再激活。
另外,如果你有多个项目同时在维护,最顺手的切换方式其实是“不切换”。每个项目根目录打开一个终端,各自执行 uv run,互不干扰。比来回 activate/deactivate 可靠得多。
6. 高频命令速查与国内镜像加速方案
这一章是给“记不住命令”的人准备的,也是我日常使用频率最高的清单。
6.1 一张表记住日常 80% 的操作
| 场景 | 命令 |
|---|---|
| 查看 uv 版本 | uv --version |
| 初始化新项目 | uv init demo |
| 安装 Python | uv python install 3.12 |
| 列出已安装 Python | uv python list --only-installed |
| 固定项目 Python 版本 | uv python pin 3.12 |
| 创建虚拟环境 | uv venv |
| 添加依赖 | uv add requests |
| 添加开发依赖 | uv add --dev pytest |
| 移除依赖 | uv remove requests |
| 按锁文件同步环境 | uv sync |
| 在项目环境里运行命令 | uv run python main.py |
| 查看依赖树 | uv tree |
| 更新 uv 自身 | uv self update |
| 查看缓存路径 | uv cache dir |
| 清理全部缓存 | uv cache clean |
这些命令在 Unix 和 Windows 上通用,不用特别区分平台。
6.2 用环境变量或 pyproject.toml 换 PyPI 源
在国内网络环境下,直接拉 PyPI 默认源偶尔会比较慢。uv 支持通过环境变量换源。PowerShell 里临时设置:
powershell复制$env:UV_INDEX_URL = "https://pypi.tuna.tsinghua.edu.cn/simple"
持久化写入用户环境变量:
powershell复制[Environment]::SetEnvironmentVariable("UV_INDEX_URL", "https://pypi.tuna.tsinghua.edu.cn/simple", "User")
这样以后 uv 安装所有包都会走清华 PyPI 镜像。想让某个项目单独走镜像,不想影响全局,可以在 pyproject.toml 里加:
toml复制[[tool.uv.index]]
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
default = true
但要注意,项目的 uv.lock 里会记录依赖来源。如果你之前已经用默认源生成过锁文件,换成镜像源后可能触发 lock 更新,这是正常现象。
除了清华,阿里云和网易的 PyPI 镜像也稳定:
powershell复制$env:UV_INDEX_URL = "https://mirrors.aliyun.com/pypi/simple/"
6.3 Python 安装镜像与缓存管理
PyPI 换源解决的是包下载速度,Python 解释器本身的下载走的不是 PyPI,而是 GitHub 上的 python-build-standalone releases。国内下载慢时,可以设置 UV_PYTHON_INSTALL_MIRROR 指向可用的镜像地址:
powershell复制[Environment]::SetEnvironmentVariable("UV_PYTHON_INSTALL_MIRROR", "https://你的镜像地址", "User")
设置完之后,新下载 Python 版本就会走这个镜像。不同镜像站时效性不一,如果你发现下载 404,换一个源再试。
缓存方面,uv 默认会把下载的包和源码放在:
code复制%LOCALAPPDATA%\uv\cache
时间长了缓存会很大。想确认具体路径:
powershell复制uv cache dir
一键清理:
powershell复制uv cache clean
清理后下次同步项目会重新下载依赖,可能比较慢,所以不建议频繁清理。
7. 更新 uv、卸载 uv、Windows 上的典型报错排查
这部分内容是我在实际使用中觉得最值得记录的,因为报错往往不在安装那一秒出现,而是在第二天、下一周、下一个新项目里冒出来。
7.1 更新:uv self update 和重装脚本的区别
uv 的迭代速度很快,旧版本可能会有 bug 或者不兼容新的 Python 版本。升级用:
powershell复制uv self update
它会自己替换当前的 uv 二进制。如果你是拿 winget 安装的,也可以:
powershell复制winget upgrade astral-sh.uv
官方安装脚本同样可以再次执行来更新。区别不大,选一种你顺手的就行。升级后建议执行 uv --version 确认一下新版本号,顺便跑一次 uv sync 验证项目环境没出问题。
7.2 报错一:无法将“uv”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
这个报错基本都是 PATH 没配置好。先在 PowerShell 里确认 uv 是否真的存在:
powershell复制Test-Path "$env:USERPROFILE\.local\bin\uv.exe"
如果返回 True,说明文件在,只是没进 PATH。把目录加进当前用户 PATH:
powershell复制$oldUserPath = [Environment]::GetEnvironmentVariable("Path", "User")
[Environment]::SetEnvironmentVariable("Path", "$oldUserPath;$env:USERPROFILE\.local\bin", "User")
然后重启终端,不要只新开标签页,要完全退出重新进,再试 uv --version。
如果 Test-Path 返回 False,说明 uv 没装成功或装到了其他位置。可以重新执行安装脚本,或者改用 winget 安装。另外,设置 UV_INSTALL_DIR 环境变量会改变安装目录,如果你之前手动设过这个变量,检查一下安装路径是否一致。
7.3 报错二:安装脚本或激活脚本被“执行策略”拦截
Windows 11 默认执行策略是 Restricted,很多脚本都跑不了。报错通常是:
code复制无法加载文件 ...,因为在此系统上禁止运行脚本
处理方式在第 2.2 节已经讲过:
powershell复制Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
这个设置只影响当前用户,不需要管理员权限,也不会对系统安全造成明显风险。设置完,执行 irm https://astral.sh/uv/install.ps1 | iex 和激活 .venv\Scripts\Activate.ps1 都会顺畅很多。
7.4 报错三:Python 下载慢或连接失败
执行 uv python install 3.12 时如果报:
code复制error sending request for url ...
大概率是下载 python-build-standalone 的资源连接失败。先确认网络能正常访问必要站点,再检查是否设置了有效的 UV_PYTHON_INSTALL_MIRROR。如果之前设置过镜像但镜像失效,会出现刚下载几步就断掉的情况。
临时跳过镜像,看看默认源是否能通:
powershell复制Remove-Item Env:UV_PYTHON_INSTALL_MIRROR
再执行 uv python install 3.12。能通就说明问题出在镜像地址上,换一个更稳定的镜像即可。
7.5 卸载 uv 前先确认这几个目录
uv 现在没有提供 uv uninstall 这种自卸命令,但官方安装脚本支持卸载参数。在 PowerShell 里执行:
powershell复制powershell -ExecutionPolicy Bypass -c "irm https://astral.sh/uv/install.ps1 | iex -Uninstall"
这会清理安装脚本生成的可执行文件,但我不确定它是否会删除所有缓存。想彻底清理的话,手动检查这几个地方:
%USERPROFILE%\.local\bin:uv.exe、uvx.exe 所在目录。%LOCALAPPDATA%\uv:缓存和托管 Python 数据目录。%APPDATA%\uv:部分配置和工具安装也可能在这里。
使用 winget 安装的同学,先执行:
powershell复制winget uninstall astral-sh.uv
再用任务计划或其他方式确认可执行文件是否残留。卸载前如果项目里已经生成了 .venv,那些虚拟环境目录也要手动删除,或者直接删掉整个项目目录重来。
我个人在实际操作中的习惯是:不需要急着卸载。uv 不是常驻后台服务,它只是一个命令行工具,放在那里不占资源。真正要清理的反而是各个项目里散落的 .venv,因为每个都有几百 MB。如果机器磁盘吃紧,删掉不需要的项目目录,然后跑一次 uv cache clean,比纠结卸载本身更有效。这大概也是 Windows 上使用 uv 时,最值得留意的一件事。
