Python 虚拟环境:venv 到底在隔离什么,一次讲清楚

举报
yd_299495290 发表于 2026/11/06 06:21:32 2026/11/06
【摘要】 刚学 Python 的人几乎都会遇到同一个场景:A 项目要 requests 2.28,B 项目却要求 2.31;系统里装的 Python 是 3.11,某个老项目却只能跑在 3.9 上。直接在全局环境里 pip install,装着装着就把环境搅成了一锅粥:这个项目能跑了,那个项目却报 ImportError。虚拟环境就是用来解决这个问题的,它的核心思想只有一句话:给每个项目一个独立的、互...

刚学 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。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。