深入理解 Python 虚拟环境
前言:Python 作为一个优秀的解释型语言,在各个计算机细分领域都有着广泛的运用。然而 Python 不同版本之间的细微不兼容性使得 Python 解释器、第三方库的管理变得很困难。
为了解决依赖问题,Python 社区发明了许多方法。本文从三个角度出发,试图解释清楚新手面对 Python 虚拟环境时经常遇到的困惑。
- Python 虚拟环境是如何创建的
- 系统如何识别并套用某个虚拟环境
- Python 虚拟环境有哪些实现且推荐使用哪个虚拟环境管理器
1. 如何理解 Python 虚拟环境·
现阶段有若干个 Python 虚拟环境生命周期管理方法,这里列举较为常用的两种:
Python 虚拟环境(Isolated Environment)看似神秘,实则非常简单,它的存在依赖于两种 Linux 对象:
PATH
环境变量- 独立的 Python 虚拟环境对应的目录
使用下列命令可以输出环境变量:
1 | echo $PATH | sed 's/:/\n/g' | sort |
查看不同虚拟环境下 PATH
环境变量的差异。
fuzzware
虚拟环境:
1 | /bin |
angr
虚拟环境:
1 | /bin |
可以明显发现, PATH
在 miniconda3 env 相关的行中,存在着与虚拟环境名相同的关键字。因此可得以下结论:Python 虚拟环境是在独立的文件夹里创建 Python 目录结构,执行虚拟环境切换时会将 PATH 中相关的字段替换为对应的虚拟环境路径。
下面是一个由 conda 创建的虚拟环境目录 layout,与 Linux 根目录布局很相似。
1 | . |
VSCode 在打开文件夹时,可以选择合适的 Python 虚拟环境。VSCode 有一套方法可以扫描系统安装的虚拟环境,但是我们之前说过,虚拟环境从存储上看就是一个文件夹,因此 VSCode 并不一定能扫描到全部的虚拟环境,必要时还得手动指定。不过使用 conda 一般没有问题。
2. 如何使用工具管理虚拟环境·
网上关于 conda 和 virtualenv 的对比已经有很详细的描述了,在此我们不再赘述。这里给出几个重要的观察:
virtualenv
是一个 Python 虚拟环境管理工具,而conda
不仅可以管理虚拟环境,还是一个高级的 Python 包管理器(与pip
类似)。pip
可以管理 Python 的第三方库,但是不会对第三方库中的 binary 做兼容性检查,而conda
的检查更为严格。conda
有自己的上游认证过的 Python 库,而且是二进制发行版,安装速度更快。conda
尽管有无数优势,但是它的库并不全,有些冷门的 Python 库还是需要用pip
安装,好在pip
是装在虚拟环境的bin
目录里,因此也可以在虚拟环境里使用用户态的pip
(不加sudo
)。
这里推荐不要安装 debian apt 仓库里的 Python,而是直接使用 conda 提供的 Python.
2.1 创建特定 Python 版本的虚拟环境·
使用 conda
命令创建 Python 3.6 版本的虚拟环境。
1 | conda create -n <ENV_NAME> python=3.6 |
2.2 列出当前安装的虚拟环境·
1 | conda env list |
2.3 将当前虚拟环境导出为 requirements.txt 文件·
将 ENV_NAME
环境中包含的所有 Python 库导出为 requirements.txt 文件:
1 | conda deactivate |
随后,可以使用如下命令重新安装所有的 Python 模块:
1 | conda install --file requirements.txt |
注意两点:
- 不要在
base
环境里做任何安装,因为base
环境在导出时会遇到一些麻烦。建议创建一个normal
环境用来日常使用,无非就是在.zshrc
里添加一行conda activate normal
而已。 - conda 导出的包里有可能包含 pip 安装的一些、conda 上游仓库中不存在的包,下次安装时 conda 找不到这种包,会直接报错,建议根据错误信息做修改。
3. 硬核观察·
用 conda 创建虚拟环境有时会非常快,因为 conda 使用硬链接机制索引 Python 组件中的重复文件,避免了从网上下载相同版本 Python 组件带来的存储开销。我们通过下面两张图的对比可以看到,在移除 test
虚拟环境之后,文件 x86_64-conda-linux-gnu-ld
的 inode 索引计数减少 1. 因此在不要求特定 Python 版本而只要求环境隔离的情况下,可以肆无忌惮地创建 Python 虚拟环境。
总结·
通过深入理解 Python 虚拟环境的实现方式,有助于用户更容易地使用 conda 等工具创建自己的虚拟环境。通过导出虚拟环境,也可以实现良好的持久化存储。不过要注意,pip
和 conda
可以共存,比如在某个虚拟环境里安装一些 conda
仓库里不存在的包,就需要用 pip
安装。此时 pip
会将包安装在虚拟环境里,而非安装在系统目录里。这时候再导出、导入就会发生问题,因为 requirements.txt
里有些包 conda
装不上,pip
能装但是版本不一定合适。因此建议,不要混用 pip
和 conda
,除非万不得已。