文章目录
- 1. 怎样算是一套Python环境?
- 2. 系统环境 VS 虚拟环境
- 3. 虚拟环境最佳实践
1. 怎样算是一套Python环境?
首先,我们得先弄清楚:怎样算是一个Python环境?然后再去区分系统环境和虚拟环境。简单地说,在安装了Python之后,我们就已经获得了一套Python环境,一套完整的Python环境应该包括:
- Python语言本身:Python解释器以及安装目录下一系列的可执行文件
- Pip:其实它只是Python标准库中的一个包,只是这个包比较特殊,是Python的包管理工具,可以查找、下载、安装和卸载各种Python包,考虑到它的特殊性,特意将其列出
- 已下载的各种依赖包:这也是Python环境的重要组成部分,通过pip下载的依赖包会存放于
Python安装目录\Lib\site-packages\
目录下
2. 系统环境 VS 虚拟环境
接下来,我们看一下所谓的“系统环境”与“虚拟环境”。在Virtualenv等工具引入之前,Python是没有“虚拟环境”这一概念的,一个Python环境指的就是在本地操作系统上安装的Python,由于Python自身版本的兼容性问题,Python用户通常会在操作系统上安装多个不同版本的Python,也就形成了多套Python环境共存的局面,我们把这些实际安装在操作系统上的Python环境统称为“(Python)系统环境”,或者叫“(Python)本地环境”。下图是我本机的一个示例,我在C:\Python\Python 3.7.9
和C:\Python\Python 3.8.6
上分别安装了Python 3.7.9
和Python 3.8.6
,因此在我的本地有两套Python系统环境:
显然,两个版本的Python系统环境并不能满足纷繁复杂的Python项目对不同包的依赖需求,于是,我们要通过Virtualenv等工具来创建虚拟环境。本质上,一套虚拟环境就是一套独立的Python环境,它包含我们在开始时列举出的一套完整Python环境的全部组成部分:Python解释器 + Pip + 未来将会下载的各种依赖包。使用Virtualenv可以帮助我们自动构建一套新的Python环境,它从一个已有的“Python系统环境”中拷贝Python解释器和Pip,但不拷贝系统环境中的任何包(也就是site-packages目录下的文件),这样,我们就可以得到一个“纯净”的Python环境。我们把这样的环境称为“虚拟环境”。
朴素一点说,虚拟环境就是借助工具便捷复制出的一套独立的Python环境,并重定向了Python的环境变量。理论上,我们可以方便地创建出任何多个虚拟环境,这要比在本地安装Python系统环境来得简单实用的多,且没有任何副作用:
对于虚拟环境有两点需要特别强调一下:
-
虚拟环境必须以一个Python系统环境/本地环境为基础(镜像)构建,以上图所示的案例,我们是无法创建出基于
Python 3.9.x
的虚拟环境的,因为本地并未安装Python 3.9.x
-
为了保证新建的虚拟环境是一个“纯净”的Python环境,Virtualenv不会拷贝原系统环境中的包,如果我们在一个新建的虚拟环境中使用pip list检查一下系统安装的包就会发现它含有标准库:
Package Version
---------- -------
pip 19.0.3
setuptools 40.8.0
wheel 0.33.1
3. 虚拟环境最佳实践
虚拟环境的标准用法是面向一个Python项目构建一个独立的虚拟环境,即Virtual Environment Per Project,所以在一台Python用户的计算机上,典型的Python环境布局往往是这样的:
- 伴随项目构建的虚拟环境最好放在项目根目录下,与项目的其他资源(代码,文档等)统一放置,这样便于管理。
- 虚拟环境目录应该添加到git的ignore文件中,不应加入版本控制
- 可以使用.前缀隐藏虚拟环境目录(如果你希望让工程目录看上去更规范一些的话)
最后是一点点探索和思考。为每一个项目构建独立的虚拟环境花费的存储成本还是很高的,一种可能的折中方案是:我们可以按照大的技术领域细分出几种虚拟环境,里面的包选择当前的主流版本,然后在创建该领域的项目时,使用同一个虚拟环境,这特别适用于以学习和研究为目的项目,对版本差异并不敏感,主要的依赖包非常明确。例如:我们可以面向Web应用开发和数据分析分别创建虚拟环境,同类型项目共用同一虚拟环境:
归纳起来说就是:我们可以从不同的维度抽象出一些具有普遍适用性的虚拟环境供多个项目共享,减少虚拟环境的数量。一些可行的维度包括:技术堆栈:Web还是数据?主要工具的版本:Spark2还是Spark3?TF1还是TF2?等等。