本节目标:在你的机器上装好一个可用的 Python 3.14,并理解虚拟环境为什么是每个项目的标配;读完后你能独立创建、激活、退出一个 venv,并说清激活时究竟改了什么。
适用版本:Python 3.12+(实测 3.14.6)
2.1 安装 Python 与虚拟环境
上一节我们讲了 CPython 的执行模型:源码先编译成字节码,再由解释器循环执行。但要让这套机制跑起来,你得先有一个解释器。本节把「装 Python」这件事拆成四步:装解释器、搞清 python 和 python3 的区别、建立虚拟环境、认识管理多版本与依赖的现代工具。
各平台安装方式
不同操作系统的默认状态差别很大,先看一张对照表。
| 平台 | 推荐方式 | 命令或来源 | 备注 |
|---|---|---|---|
| macOS | Homebrew | brew install python@3.14 | 安装到 /opt/homebrew,不覆盖系统 Python |
| Windows | 官方安装器 | python.org 下载 python-3.14.x-amd64.exe | 勾选「Add python.exe to PATH」 |
| Windows | py launcher | py -3.14 | 官方安装器会一并装上,用于切换版本 |
| Linux | 发行版包 | sudo apt install python3.14 | 版本常偏旧,视发行版而定 |
| Linux | 源码编译 | ./configure && make | 需要新版或定制编译选项时使用 |
macOS。 系统自带的 /usr/bin/python3 是 Apple 为自家工具链保留的,版本落后且不要去动它。用 Homebrew 装一个新版本最省心:
brew install python@3.14
python3.14 --version
Homebrew 会同时建立 python3 指向 python3.14 的软链接,但不会创建名为 python 的命令——这是刻意的,避免和系统或其它工具冲突。
Windows。 从 python.org 下载官方安装器时,务必勾选「Add python.exe to PATH」,否则命令行里找不到 python。安装器还会附带 py 启动器,它是 Windows 上管理多版本的正解:
py -3.14 --version
py --list
py --list 会列出你机器上所有已注册的解释器,py -3.14 则精确选中 3.14。注意别用 Microsoft Store 版本的 python,它是个重定向存根,行为和标准安装器不一致,容易在排查问题时误导你。
Linux。 发行版仓库里的 Python 往往落后一两个小版本。Ubuntu 用户要装更新版本,可以加 deadsnakes PPA;追求可控性的人则直接源码编译:
./configure --prefix=/opt/python3.14 --enable-optimizations
make -j"$(nproc)"
sudo make altinstall
用 altinstall 而不是 install,是为了不覆盖系统的 python3。--enable-optimizations 会跑 PGO 优化,编译慢一些但运行更快。
python 还是 python3:一段历史包袱
如果你刚接触 Python,一定会被这件事绕晕:有的教程写 python foo.py,有的写 python3 foo.py,到底该用哪个?
根源在 Python 2 与 Python 3 的长期并存。早年 python 命令普遍指向 Python 2,而 Python 3 的二进制被命名为 python3 以示区分。后来 Python 2 于 2020 年停止维护,社区推动统一,但各平台进度不一,于是就有了今天的混乱局面。
| 环境 | python 指向 | 建议 |
|---|---|---|
| macOS(系统) | 通常不存在 | 用 python3 或 python3.14 |
| macOS(Homebrew) | 通常不存在 | 用 python3 |
| Windows(官方安装器) | 可能指向安装的版本 | 优先用 py -3.14 |
| Linux(多数发行版) | 可能不存在,或指向 python3 | 用 python3 |
| 虚拟环境内 | 一定指向该环境的解释器 | 随便用 |
这份混乱催生了 PEP 394 的建议:在跨平台的脚本里用 python3。不过一旦进入虚拟环境,python、python3、python3.14 三个名字都会指向同一个解释器,此时用哪个都行——这也是我们下一节要建立虚拟环境的原因之一。
为什么必须用虚拟环境
先设想一个没有虚拟环境的世界。你装了 Python,所有 pip install 装的包都进同一个全局 site-packages 目录。现在:
- 项目 A 需要
requests==2.28,项目 B 需要requests==2.34,两者只能装一个,另一个必然被覆盖; - 你升级某个包修 A 的 bug,结果 B 突然跑不起来了;
- 你想知道「这个项目到底依赖哪些包」,全局目录里几百个包混在一起,无从下手;
- 你的项目交给同事,对方环境里没装某个包,代码直接崩。
虚拟环境的思路很简单:为每个项目开一份独立的 site-packages。项目的解释器、依赖、版本都被隔离在一个目录里,互不干扰。删掉目录就等于彻底卸载,不留残留。
venv:标准库自带
从 Python 3.3 起,venv 就是标准库的一部分,不需要额外安装。创建一个虚拟环境只要一行:
python3.14 -m venv .venv
约定俗成把目录命名为 .venv(前导点让它默认隐藏,且已被各类工具识别)。创建后目录结构如下:
.venv/
├── bin/ # Linux/macOS:可执行文件与激活脚本
├── include/ # 供 C 扩展编译用的头文件
├── lib/ # 该环境私有的 site-packages
└── pyvenv.cfg # 环境元数据
在 Windows 上,可执行文件位于 Scripts/ 而非 bin/,这是唯一需要留意的差异。
pyvenv.cfg 是这个环境的身份证,记录了它从哪来、能不能看到系统包、对应哪个版本。下面是本节实测生成的一份真实内容:
home = /opt/homebrew/opt/python@3.14/bin
include-system-site-packages = false
version = 3.14.6
executable = /opt/homebrew/Cellar/python@3.14/3.14.6/Frameworks/Python.framework/Versions/3.14/bin/python3.14
command = /opt/homebrew/opt/python@3.14/bin/python3.14 -m venv /private/tmp/pybook_test/.venv
逐行读一遍:home 指向基础解释器所在的 bin 目录;include-system-site-packages = false 表示这个环境看不到全局包,这正是隔离的关键;version 是解释器版本;executable 是基础解释器的真实路径;command 记录了创建时执行的完整命令。
看一眼 bin/ 目录里的内容:
ls -1 .venv/bin
activate
activate.csh
activate.fish
Activate.ps1
pip
pip3
pip3.14
python
python3
python3.14
𝜋thon
前四个是给不同 shell 用的激活脚本。pip、python 及其带版本号的名字都是指向基础解释器的符号链接——它们看起来是复制品,其实只是同一份解释器的别名。最后那个 𝜋thon(用希腊字母 π 拼的「python」)是 3.14 加入的一个彩蛋别名,能用,但不建议写进正式脚本。
激活、退出与「激活到底改了什么」
创建好之后,要「进入」这个环境,执行激活脚本:
source .venv/bin/activate # Linux / macOS
.venv\Scripts\activate # Windows
激活后命令提示符前会出现 (.venv) 前缀。退出则用:
deactivate
很多人以为「激活」是个黑魔法,其实它只做了一件小事:把环境的 bin/ 目录插到 PATH 最前面。下面是本节实测的对比(路径已省略中段):
echo "$PATH" # 激活前
source .venv/bin/activate
echo "$PATH" # 激活后
# 激活前
/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin:...
# 激活后
/private/tmp/pybook_test/.venv/bin:/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin:...
差别就是最前面多了 .venv/bin。由于 PATH 从左到右查找,python、pip 这些命令自然就命中了虚拟环境里的版本,而不再命中系统版本。除此之外,激活脚本还设置了一个环境变量:
echo "$VIRTUAL_ENV"
/private/tmp/pybook_test/.venv
VIRTUAL_ENV 指向环境根目录,供 pip、编辑器等工具识别当前环境。验证一下解释器确实换了:
python -c "import sys; print(sys.prefix); print(sys.base_prefix)"
/private/tmp/pybook_test/.venv
/opt/homebrew/opt/python@3.14/Frameworks/Python.framework/Versions/3.14
sys.prefix 是当前环境,sys.base_prefix 是基础解释器。两者不同,说明虚拟环境生效了。
这里有个常被忽略的事实:激活并非必需。你完全可以直接调用环境里的解释器,效果一样:
.venv/bin/python hello.py
激活只是省去了每次敲完整路径的麻烦,并让 pip 等工具知道该往哪儿装。写脚本、配 CI 时,直接写全路径反而更明确、更不容易出错。
pyenv:管理多个解释器版本
虚拟环境隔离的是依赖,但如果你同时需要 Python 3.11 和 3.14 两个解释器本身呢?这就要靠版本管理器。pyenv 是最经典的一个(最新发布为 v2.8.8):
pyenv install 3.14.6
pyenv versions
pyenv global 3.14.6 # 设置默认版本
pyenv local 3.12.10 # 为当前目录指定版本,写入 .python-version
pyenv local 会在当前目录生成 .python-version 文件,进入该目录时自动切换到指定版本。这个文件应该提交进 Git,让团队用上一致的解释器。
需要留意的是,pyenv 接管的是 python 命令的解析,它和 venv 是互补而非竞争关系:通常先用 pyenv 选定解释器版本,再用 venv 为项目隔离依赖。
uv:新一代工具
uv 是近年崛起的一体化工具,用 Rust 写成,把解释器安装、虚拟环境、依赖解析、锁文件全部收进一个命令(最新版本 0.12.23)。它可以直接下载并管理解释器:
uv python install 3.14
uv python list
创建虚拟环境比 venv 更快,且默认就会挑选合适的解释器:
uv venv --python 3.14
Using CPython 3.14.6 interpreter at: /opt/homebrew/opt/python@3.14/bin/python3.14
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate
注意 uv 创建的 .venv 与 python -m venv 创建的完全兼容——都是标准虚拟环境,同样用 source .venv/bin/activate 激活。两者的差别只在创建速度和默认行为,产物本身通用。至于 uv 在依赖管理和项目结构上的完整能力,我们在 2.3 节和后续章节展开,你也可以先看专题文章 现代 Python 工具链
做延伸阅读。
小结
- 各平台安装方式不同:macOS 用 Homebrew,Windows 用官方安装器加
py启动器,Linux 用发行版包或源码编译。 python与python3的分裂源于 Python 2/3 并存的历史,跨平台脚本建议统一用python3,虚拟环境内则无所谓。- 虚拟环境的核心价值是隔离:每个项目一份独立的
site-packages,依赖互不干扰。 python -m venv .venv创建环境,pyvenv.cfg记录元数据,include-system-site-packages = false保证隔离。- 激活的本质是把环境
bin/目录插到PATH最前面,并设置VIRTUAL_ENV;不激活而直接调用.venv/bin/python同样有效。 pyenv管解释器版本,uv把版本、环境、依赖一把抓,二者都能和venv配合使用。
环境装好只是第一步。接下来你得有个地方写代码、有个地方试代码——编辑器怎么选、解释器怎么配、REPL 怎么用、第一个脚本怎么写,都是下一节 2.2 编辑器、REPL 与第一个脚本 的内容。如果你对「为什么 Python 要区分解释器和虚拟环境」背后的执行模型还有疑问,可以回看 1.3 解释器实现与执行模型 。
阅读导航:上一节:1.3 解释器实现与执行模型 · 下一节:2.2 编辑器、REPL 与第一个脚本 。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。