python虚拟环境venv简介
Python 虚拟环境(Virtual Environment)是一个极其重要的概念,可以把它想象成每个 Python 项目都有一个独立的“沙盒”或“房间”。所有虚拟环境共用系统全局的 Python 解释器,但每个虚拟环境都有自己独立的依赖包库。
1. 为什么需要虚拟环境
想象一下,你的电脑是一个大房子,Python 是房子里的工具箱。
❌ 没有虚拟环境的情况(全局安装):
- 你所有的工具(库/包)都扔在客厅的大箱子里。
- 项目 A 需要
numpy 1.20版本。 - 项目 B 需要
numpy 1.25版本。 - 当你为项目 B 更新 numpy 时,项目 A 就崩溃了,因为它依赖旧版本。
- 更糟糕的是,如果你不小心删错了文件,所有项目都可能受影响。
- 这就是所谓的 “依赖冲突” 和 “环境污染”。
✅ 有虚拟环境的情况(隔离安装):
- 每个项目都有自己独立的小房间(虚拟环境)。
- 项目 A的房间里放着
numpy 1.20。 - 项目 B的房间里放着
numpy 1.25。 - 两个房间互不干扰。你在项目 B 里怎么折腾,都不会影响项目 A。
- 当你想分享项目给同事时,只需要告诉他:“进这个房间,里面的工具都是配好的。”
2. 虚拟环境到底做了什么
当你运行 python3 -m venv .venv 创建虚拟环境时,Python 做了以下几件事:
- 复制解释器:它在
.venv文件夹里创建了一个指向当前 Python 解释器的副本(或链接)。 - 独立库目录:它创建了一个空的
site-packages文件夹,专门用来存放这个项目安装的库。 - 激活脚本:它生成了一些脚本(如
activate),用于切换当前终端的环境状态。
关键点:虚拟环境不是重新安装了一个完整的 Python,它只是创建了一个隔离的空间,让 pip install 安装的包只存在于这个空间里。
3. 如何使用虚拟环境
假设你正在开发一个名为 my_project 的项目。
第一步:创建虚拟环境
在项目根目录下运行:
python3.12 -m venv .venv
此时目录下多了一个 .venv 文件夹。
第二步:激活虚拟环境
你必须“进入”这个环境,才能使用它。以macOS / Linux为例:
source .venv/bin/activate
激活成功标志:你的命令行提示符前面会出现了 (.venv) 字样
(.venv) user@computer:~/my_project$
第三步:安装依赖
现在你安装的包只会在这个虚拟环境里:
pip install requests pandas
第四步:开发代码
正常运行你的 Python 脚本即可,它会自动使用环境里的 Python 和库。
第五步:退出虚拟环境
做完工作后,退出环境:
deactivate
提示符前的 (.venv) 消失,回到系统全局环境。
4. 如何保存和复现环境
为了让别人也能在你的项目上运行,你需要记录“房间里有哪些工具”。
4.1 导出依赖列表
在激活虚拟环境后,运行:
pip freeze > requirements.txt
这会生成一个 requirements.txt 文件,内容类似:
requests==2.31.0
pandas==2.1.1
numpy==1.25.2
4.2 复现环境
别人拿到你的项目后:
- 创建新的虚拟环境:
python3 -m venv .venv - 激活环境:
source .venv/bin/activate - 一键安装所有依赖:
pip install -r requirements.txt
这样,别人就能拥有和你完全一致的开发环境!
5. 虚拟环境与python解释器的关系
虚拟环境并没有复制一个完整的 Python 解释器,它只是创建了一组指向系统全局 Python 解释器的“快捷方式”或“链接”,并配合一个独立的包存储目录。可以把它们关系理解为:“同一个大脑(解释器),不同的记忆库(包)”。
5.1 核心关系图解
假设系统中安装了 Python 3.12位于 /usr/bin/python3.12。当运行 [ python3.12 -m venv .venv] 后,.venv 文件夹结构如下(以 Linux/macOS 为例):
.venv/
├── bin/
│ ├── python ---> 符号链接 (Symlink) 指向 /usr/bin/python3.12
│ ├── python3 ---> 符号链接 (Symlink) 指向 /usr/bin/python3.12
│ └── pip ---> 一个脚本,配置为只操作 .venv/lib/... 下的包
├── lib/
│ └── python3.12/
│ └── site-packages/ <--- 【关键】这里存放该项目独有的第三方库
└── pyvenv.cfg <--- 配置文件,告诉 Python "我是虚拟环境"
文件夹内容详解:
-
解释器本体(Binary):
- 虚拟环境中的
bin/python不是一个新的可执行文件。 - 它是一个符号链接(Symbolic Link),直接指向你创建时指定的那个全局 Python 解释器(如
/usr/bin/python3.12)。 - 这意味着:无论你在多少个虚拟环境中,它们共享同一个底层的 Python 核心代码、标准库(如
os,sys,json)和性能特性。
- 虚拟环境中的
-
包管理路径(Site-packages):
- 虽然解释器是同一个,但虚拟环境通过修改环境变量(主要是
PATH和PYTHONHOME),欺骗了解释器。 - 当你在虚拟环境中运行
import requests时,Python 解释器会优先去.venv/lib/python3.12/site-packages/查找,而不是去全局的/usr/lib/python3.12/site-packages/查找。 - 这就是隔离的本质:解释器没变,但它“看”到的库变了。
- 虽然解释器是同一个,但虚拟环境通过修改环境变量(主要是
-
配置文件(pyvenv.cfg):
- 这个文件告诉 Python 解释器:“嘿,你现在处于一个虚拟环境中,请忽略全局的 site-packages,只看我这里的。”
5.2 全局 Python vs 虚拟环境中的 Python
| 特性 | 全局 Python (/usr/bin/python3.12) |
虚拟环境中的 Python (.venv/bin/python) |
|---|---|---|
| 物理文件 | 真实的二进制可执行文件 | 符号链接,指向全局 Python |
| 版本 | 固定(如 3.12.1) | 完全相同(因为指向同一个文件) |
| 标准库 | 使用全局的标准库 | 使用全局的标准库(因为解释器一样) |
| 第三方库路径 | /usr/lib/.../site-packages |
.venv/lib/.../site-packages |
| 独立性 | 所有项目共享,易冲突 | 独立,每个环境有自己的库 |
| 创建成本 | 需安装整个 Python | 极速(只需创建链接和文件夹) |
5.3 如何验证这种关系
可以在终端中亲自验证这种关系。
第一步:查看全局 Python 路径
$ which python3.12
/usr/bin/python3.12
第二步:创建并激活虚拟环境
$ python3.12 -m venv .venv
$ source .venv/bin/activate
第三步:查看虚拟环境中的 Python 路径
(.venv) $ which python
/home/user/project/.venv/bin/python
第四步:查看它是否是指向全局的链接
- "箭头
->"就证明它是一个符号链接,指向全局解释器。
(.venv) $ ls -l $(which python)
lrwxrwxrwx 1 user user ... /home/user/project/.venv/bin/python -> /usr/bin/python3.12
第五步:查看包路径的不同
(.venv) $ python -c "import sys; print(sys.path)"
# 输出中会包含 '.venv/lib/python3.12/site-packages'
# 而不会包含全局的 site-packages(除非特别配置)
5.4 为什么这样设计
1. 节省空间:
- 如果每个虚拟环境都复制一份完整的 Python(包括标准库、二进制文件),每个环境可能要占用 100MB+。
- 使用链接后,每个虚拟环境只占用几 MB(主要是你安装的第三方库)。
2. 保持一致性:
- 确保虚拟环境中的 Python 行为与系统安装的 Python 完全一致(同样的 bug,同样的性能,同样的 C 扩展兼容性)。
3. 易于升级:
- 如果你升级了系统全局的 Python 3.12(比如从 3.12.1 升到 3.12.2),所有指向它的虚拟环境会自动获得更新后的解释器内核(只要二进制接口兼容)。
5.5 总结
- 虚拟环境 ≠ 新的 Python 安装。
- 虚拟环境 = 全局 Python 解释器的快捷方式 + 独立的第三方库文件夹。
- 关系:虚拟环境依赖于全局解释器存在。如果删除了全局的 Python 3.12,所有基于它创建的虚拟环境都会失效(因为链接断了)。
6. 常见疑问
Q1: 虚拟环境会占用很多磁盘空间吗?
- 不会太多。它主要占用的是你安装的库的空间。Python 解释器本身是通过链接引用的,不会重复复制几个 GB 的文件。
- 如果项目很小,虚拟环境可能只有几十 MB。
Q2: 我需要为每个项目都创建虚拟环境吗?
- 强烈建议是的。这是 Python 开发的最佳实践。
- 即使是很小的脚本,养成这个习惯能避免未来的麻烦。
Q3: .venv 文件夹要上传到 Git 吗?
- 绝对不要!
.venv包含特定于你操作系统的二进制文件,其他人无法直接使用。- 你应该在
.gitignore文件中添加.venv/,只上传requirements.txt。
Q4: 虚拟环境和 Conda 有什么区别?
venv是 Python 自带的,轻量级,只管理 Python 包。Conda是一个更强大的包和环境管理器,可以管理非 Python 依赖(如 C 库、R 语言等),常用于数据科学领域。- 对于大多数 Web 开发或通用 Python 项目,
venv足够且更简单。
Q5: 虚拟环境.venv文件夹能否移动?
- 不能移动!
- 虚拟环境被移动后,内部的路径引用全部失效了。
-
虚拟环境在创建时,会把绝对路径硬编码 到多个配置文件中,比如:
-
.venv/bin/activate→ 里面硬编码了VIRTUAL_ENV="/创建时路径/.venv" -
.venv/pyvenv.cfg→ 记录了home = /opt/homebrew/bin等路径信息
-
-
当移动.venv文件夹后,这些内部记录的路径和实际位置不匹配了,虚拟环境失效
Q6: 我想给虚拟环境换个目录该怎么办?
- 虚拟环境不能移动,只能在新位置重新创建。
- 操作如下:
- 删除旧路径的虚拟环境:rm -rf /xxx-old-path/.venv
- 在新位置重新创建:python3.12 -m venv .venv
- 激活并安装依赖: source .venv/bin/activate , pip install xxx
Q7: 虚拟环境里怎么该项目的python解释器?
- PyCharm
-->Settings-->Project:my_xx_project --> Python Interpreter --> Add Interpreter --> Add Local Interpreter -->进入python解释器配置页面,解释器路径设置为“my_xx_project/.venv/bin/python”
更多推荐



所有评论(0)