Python 虚拟环境完全指南:venv、virtualenv 与 Conda详解

发布时间:2026/10/8 16:02:30
Python 虚拟环境完全指南:venv、virtualenv 与 Conda详解 前言把venv、virtualenv、Conda三个名字并列很容易让人以为它们是同一个东西的三代版本选新的就行。这个理解是错的。它们的定位差别其实很大venv和virtualenv是 Python 专属的包隔离工具Conda则是一个跨语言的包管理器与环境管理器——它不仅能装 Python 包还能装编译器、CUDA、R 语言、系统库它管的是一整套二进制环境Python 只是其中一员。换句话说Conda严格来说不是Python 的虚拟环境虽然它最常被这么用。本文把三者的边界划清楚再给出选取原则最后说明混用时要小心什么。关于Conda与virtualenv的具体命令细节请以各自的官方文档为准本文对venv的描述依据 Python 官方文档。一、venv标准库零依赖的默认答案venv从 Python 3.3 起进入标准库官方文档写明自 Python 3.5 起推荐用它创建虚拟环境。它做的事情很克制建一个目录放一份指向创建它的解释器的副本或符号链接配置一个独立的site-packages仅此而已。# 创建并用环境里的解释器python -m venv .venv它的最大优势是不需要安装任何东西任何一台装了 Python 3.3 的机器上都能立刻用。代价是功能相对基础它不负责依赖解析那是 pip 的活不锁定版本也没有环境清单文件的原生支持。它也不支持 Python 2——在 Python 2 还是主流的年代这件事得靠virtualenv。二、virtualenv标准库之外的老前辈virtualenv比venv出现得早是第三方包需要pip install virtualenv。在venv进入标准库之前它是事实标准。venv的实现本身就大量借鉴了virtualenv的思路。它今天仍然有价值的场景主要有两类一是需要兼容仍然使用 Python 2 的遗留项目这类项目在 2020 年 Python 2.7 停止维护后应尽快迁移但存量确实存在二是需要一些venv没有提供的额外能力具体有哪些选项以其官方文档为准。对绝大多数新项目而言如果只需要隔离依赖这一个功能venv已经足够不必额外引入一个依赖。选择路径很清晰能用venv就用venv只在确实撞到它不支持的边界时再考虑virtualenv。三、Conda跨语言的包与环境管理器Conda的抽象层级和上面两者完全不同。它管理的是环境环境里可以同时有 Python、编译工具链、二进制库和其它语言的运行时。它有自己的频道channel体系如conda-forge来分发预编译好的包这正是它在科学计算、深度学习领域流行的原因——很多涉及 CUDA、BLAS 这类底层二进制的包用pip装起来很痛苦用conda往往一条命令就好。它的典型用法以下命令请以 Conda 官方文档为准# 创建一个指定 Python 版本的环境conda create -n myenv python3.11# 激活 / 退出conda activate myenvconda deactivate# 装包conda install numpy# 导出环境清单 / 从清单复现conda env export environment.ymlconda env create -f environment.ymlConda的环境和venv的虚拟环境在概念上有重叠所以很容易被混为一谈。区别在于venv环境永远依附于某个已安装的 PythonConda环境则自带 Pythonconda create时你指定版本它把解释器一起装进环境。这也意味着Conda环境不依赖系统里的 Python。维度venvvirtualenvConda来源标准库自带第三方包独立发行版自成一个生态是否需安装否是是装 Miniconda/Anaconda隔离范围仅 Python 包仅 Python 包跨语言含二进制与非 Python 依赖自带 Python否依附已有解释器否是可指定版本主要包来源PyPIpipPyPIpipConda 频道也可用 pip 作为补充典型场景通用 Web/脚本项目兼容旧 Python、进阶需求数据科学、深度学习、复杂二进制依赖清单文件无原生支持靠pip freeze无原生支持environment.yml四、怎么选按依赖的性质决定选择的关键问题不是哪个更先进而是你的依赖里有没有非 Python 的二进制。如果项目依赖的是纯 Python 包或者依赖的轮子wheel在 PyPI 上已经有各平台的预编译版本那venvpip是最轻、最标准、最好协作的方案别人git clone后两条命令就能跑不需要先装一个几百 MB 的发行版。如果项目依赖大量科学计算库、GPU 相关库或者需要在同一个环境里固定一整组二进制版本比如特定的 CUDA 组合那Conda的频道体系会帮你省下大量折腾代价是环境体积大、生态自成一体、与纯pip工作流需要一些协调。一个务实的中间策略是用Conda管 Python 版本和那些难装的二进制包用pip装纯 Python 的包。但要注意混用会让环境状态变得难以追踪所以应当固定一个主包管理器负责大多数安装pip作为明确的补充手段并把两边的依赖都记录下来。五、混用时要注意什么最需要警惕的是把Conda环境和venv叠加或者在不同环境下反复横跳导致pip指向错位。判断当前处在什么环境里可以用前面提到的前缀检查Conda环境同样会让sys.prefix与之不同。# 适用于 Python 3.8import sysprint(解释器:, sys.executable)print(环境:, sys.prefix)print(是否隔离环境:, sys.prefix ! sys.base_prefix)另外无论用哪种工具激活都只影响当前终端会话IDE、定时任务、CI 有各自的解释器选择方式不要假设激活状态会跨场景传递。切换工具时也记得清理不再使用的旧环境目录——它们占的是实打实的磁盘空间。常见坑点❌ 认为Conda就是Python 的虚拟环境✅Conda是跨语言的包与环境管理器只是能用来管理 Python 环境它自带解释器而venv依附已有解释器❌ 新项目明明只需要隔离依赖却先装了完整的 Conda 发行版✅ 纯 Python 依赖用venvpip更轻、更易协作Conda 留给有复杂二进制依赖的场景❌ 以为venv在 Python 2 上也能用✅venv自 Python 3.3 起才有且不支持 Python 2旧项目才需要virtualenv❌ 在Conda环境里反复用pip install环境状态变得不可复现✅ 固定一个主包管理器pip只作为明确补充并同时记录两边的依赖❌ 以为装了virtualenv才有虚拟环境✅venv是标准库python -m venv开箱即用virtualenv是可选的老牌第三方实现❌ 只看提示符判断在哪个环境里✅ 提示符可被自定义用sys.prefix/sys.executable确认真实情况❌ 用pip freeze去记录 Conda 环境里的非 Python 依赖✅pip freeze只看得见 Python 包Conda 场景该用environment.yml❌ 切换工具后旧环境目录留着不管✅ 每个环境都占磁盘不再使用的目录应清理Conda 用其自身的环境删除命令总结你的情况推荐普通 Python 项目纯 PyPI 依赖venvpip需要兼容旧 Python 或特殊隔离需求virtualenv数据科学、GPU、需要非 Python 二进制Conda想用 Conda 管二进制、pip 管纯 Python 包可以但要固定主管理器并记录两边依赖三者的关系不是新旧替代而是解决不同层次的问题venv和virtualenv在同一层竞争Python 包隔离Conda站在更高一层跨语言的整套环境。先问自己的依赖里有没有非 Python 的东西答案是否定的就用venv是肯定的再考虑Conda。