Python 虚拟环境:venv 到底在隔离什么,一次讲清楚
刚学 Python 的人几乎都会遇到同一个场景:A 项目要 requests 2.28,B 项目却要求 2.31;系统里装的 Python 是 3.11,某个老项目却只能跑在 3.9 上。直接在全局环境里 pip install,装着装着就把环境搅成了一锅粥:这个项目能跑了,那个项目却报 ImportError。虚拟环境就是用来解决这个问题的,它的核心思想只有一句话:给每个项目一个独立的、互不干扰的 Python 运行环境。
一、venv 到底隔离了什么
Python 3.3 自带的 venv 模块创建的虚拟环境,本质上是一个目录,里面有三样东西:一个指向系统解释器的 python 可执行文件、一套独立的 site-packages 目录,以及一份记录解释器路径的配置文件。激活虚拟环境后,shell 的 PATH 会被临时改写,python 和 pip 指向的都是虚拟环境里的副本;pip install 安装的包只会落进这个环境自己的 site-packages,不会碰全局环境。需要强调的是,虚拟环境并没有复制整个 Python 解释器,它只是通过符号链接复用系统解释器,体积很小,创建几乎是瞬间完成的。
二、创建与激活:三条命令就够
在项目根目录下执行 python -m venv .venv,会在当前目录生成 .venv 文件夹。Windows 上用 .venv\Scripts\activate 激活,macOS 和 Linux 上用 source .venv/bin/activate。激活成功后命令行前面会出现 (.venv) 前缀,这就是当前环境已被隔离的标志。用 which python(Windows 上用 where python)可以验证:它应当指向 .venv 里面的解释器,而不是系统路径。退出时输入 deactivate 即可。
三、容易踩的四个坑
第一个坑是在虚拟环境外面装包:忘记激活就 pip install,包又装回了全局。养成习惯,先看命令行有没有 (.venv) 前缀再装包。第二个坑是把 .venv 提交进 Git:虚拟环境目录动辄几百兆,而且和机器强相关,应当在 .gitignore 里加上 .venv/,只提交 requirements.txt。第三个坑是直接复制 .venv 文件夹换机器用:里面的绝对路径和符号链接会失效,正确做法是在新机器上重新创建环境,再用 pip install -r requirements.txt 还原依赖。第四个坑是解释器版本搞混:venv 只能隔离包,不能切换 Python 大版本;如果项目需要 Python 3.9,而系统只有 3.12,就要先装好 3.9,再用 python3.9 -m venv .venv 创建。
四、依赖管理:让环境可以重建
一个可重建的环境比一个能跑的环境更重要。开发过程中用 pip freeze > requirements.txt 定期导出依赖;接手项目的人按三步走:创建虚拟环境、激活、pip install -r requirements.txt。导出前先用 pip list 检查一遍,把调试时顺手装的、与项目无关的包清理掉,避免 requirements.txt 变成垃圾场。团队协作时,把 Python 版本要求写进 README,和 requirements.txt 放在一起,新人照着做就能复现出同样的环境。
五、venv、virtualenv 和 conda 怎么选
三者都能做隔离,但定位不同。venv 是标准库自带、零依赖的轻量选择,绝大多数纯 Python 项目用它就够了。virtualenv 功能更丰富,创建速度更快,还能指定任意已安装的解释器,适合需要精细控制的老项目。conda 则不只是 Python 环境管理器,它能管理 Python 之外的系统级依赖和不同版本的解释器,在数据科学、机器学习这类重度依赖原生库的场景里更顺手。如果只是写 Web 后端、写脚本、做自动化,venv 是最简单的答案;如果项目同时依赖特定版本的 CUDA、GDAL 这类系统库,再考虑 conda。
虚拟环境不是什么高深技术,它只是把“各项目的依赖互不干扰”这件小事,用目录和 PATH 做了制度化。理解了它隔离的是包目录和解释器入口,而不是复制整个 Python,就不会再被各种报错牵着走:先确认当前在哪个环境,再谈依赖问题。把这套流程跑顺,以后每接一个新项目,第一步永远是 python -m venv .venv。
- 点赞
- 收藏
- 关注作者
评论(0)