购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.4 Python虚拟环境

Python之所以强大,除了其本身的特性强大,更重要的是Python拥有非常多的第三方工具。强大的软件库,让开发人员将精力集中在业务上,从而避免重复“造轮子”的浪费。但众多的软件库形成了复杂的依赖关系,加上Python 2和Python 3两个大版本的兼容性问题,这些对管理项目依赖造成了不少困扰。

在使用Python时,我们可以通过pip来安装第三方工具,但是由于pip的特性,系统中只能安装每个第三方工具的一个版本。但是在实际项目开发时,不同项目可能需要第三方工具的不同版本,这迫使我们需要根据实际需求不断进行更新或卸载相应的第三方工具。而如果我们直接使用本地的Python环境,会导致整体的开发环境相当混乱而不易管理,这时候我们就需要开辟一个独立干净的空间进行开发和部署。

在创建新项目时创建一个虚拟环境,这样做的好处是把项目环境和操作系统环境分开,避免影响操作系统环境。如果不创建虚拟环境,一股脑地使用pip install安装包,那么安装的包会统一放到操作系统的Python解释器目录的site-packages文件夹下,每新建一个项目,操作系统会自动把site-packages下的所有包都导入,这会使版本管理混乱。

接下来,我们将逐一阐述Python的基本概念、pipenv特性、pipenv安装、创建虚拟环境、pipenv管理依赖、pipenv安装依赖工具包、常用命令、部署迁移虚拟环境共8块内容。

1.4.1 基本概念

我们先解释几个Python中常用的基本概念,方便大家理解后续的内容。

Python版本。Python版本指的是Python解析器本身的版本。由于Python 3不能与Python 2兼容,两大“阵营”之争持续了很长时间,因此一些软件库需要适配两种版本的Python。同时,开发人员可能需要在一个环境中,部署不同版本的Python,对开发和维护造成了麻烦。

Python包库。包库或者软件源是Python第三方工具包的集合,可以发布、下载和管理软件包,其中pip一般是从PyPI官网上查找、下载工具安装包的。为了提高下载速度,世界上有很多PyPI的镜像服务器,在国内也有多个软件源。

虚拟环境。虚拟环境并不是什么新技术,它主要利用操作系统中环境变量和进程间环境隔离的特性,Python的虚拟环境就是利用这个特性构建的。在激活虚拟环境时,激活脚本会将操作系统的环境变量PATH修改为当前虚拟环境的路径,这样后续执行命令时就会在虚拟环境的路径中查找,从而避免了在原本路径查找,从而实现了Python环境的隔离。

第一次安装Python后,我们就有了一个全局级别的,或者系统级别的环境。我们可以使用虚拟环境工具在全局环境的基础上创建多个相互独立、互不影响的虚拟环境,在这些虚拟环境中可以安装不同版本的包库。从本质上来说,虚拟环境就是相互独立的文件夹,内含Python解释器和相关依赖。

使用虚拟环境的好处显而易见:

保持全局环境的干净;

指定不同的依赖版本;

方便记录和管理依赖。

1.4.2 pipenv特性

常见的虚拟环境管理工具有virtualenv、virtualenvwrapper、pipenv、conda等,本节将重点讲解pipenv这个工具。

pipenv类似virtualenv,它是一种Python包管理工具,能自动处理各种工具之间的依赖关系,也能解决不同项目对于同一个工具有不同版本需求,而产生的同工具不同版本冲突的问题。pipenv就是pip和virtualenv的结合体,它的出现解决了原有的pip、virtualenv、requirements.txt的工作方式的局限和弊端,能够更有效地管理Python的多个环境、各种第三方工具。pipenv能解决的问题如下。

requirements.txt依赖管理的局限。使用requirements.txt管理依赖的时候可能会出现版本不确定的构建问题。

多个项目依赖不同版本第三方工具的问题。例如,应用程序A需要特定模块的1.0版本但应用程序B需要该模块的2.0版本,当我们在A和B应用程序间切换时,需要不断检测、卸载、安装该模块。这意味着只安装一个版本的模块可能无法满足每个应用程序的要求,因此需要创建虚拟环境来将A、B应用程序所需的第三方工具包分隔开来。

pipenv很好地解决了上述的两大问题,因此具备如下特性,

pipenv集成了pip、virtualenv两者的功能且完善了两者的一些缺陷。pipenv使用Pipfile和Pipfile.lock,这使得对工具包的管理更为明确。

pipenv让使用者可以深入地了解第三方工具包的依赖关系图。我们使用命令pipenv graph即可查看第三方工具包的依赖关系图。

1.4.3 pipenv安装

pipenv的安装依赖于pip,如果没有配置和安装好pip,需要先安装pip。如果系统中是Python 3,那么可以直接使用pip3进行安装。pipenv安装过程如图1-11所示。命令为pip3 install pipenv -i https://pypi.tuna.tsinghua.edu.cn/simple/,其中,-i表示采用指定的地址进行下载安装。

图1-11 pipenv安装过程

pipenv安装完成后如图1-12所示,在pip相同的目录下会生成pipenv工具的相关文件。

图1-12 pipenv安装成功

1.4.4 创建虚拟环境

接下来,通过如下命令创建一个在指定目录下的全新虚拟环境。

(1)创建目录demo的命令为mkdir demo。

(2)进入目录demo的命令为cd demo。

(3)指定使用Python 3.9.8创建虚拟环境,否则为本地默认版本,命令为pipenv install--python/ usr/local/Python-3.9.8/bin/python3。

pipenv创建虚拟环境成功如图1-13所示。

图1-13 pipenv创建虚拟环境成功

安装完成后会在项目目录demo下自动生成Pipfile和Pipfile.lock两个文件,目录demo下的文件如图1-14所示,虚拟环境就是通过这两个文件进行管理依赖的。

图1-14 目录demo下的文件

1.4.5 pipenv管理依赖

pipenv使用Pipfile代替requirement.txt文件来记录Python第三方工具的信息,另外增加Pipfile.lock文件来锁定Python第三方工具的包名、版本和依赖关系的列表。

项目提交时,可将Pipfile文件和Pipfile.lock文件提交,待其他开发人员下载,根据此Pipfile文件,执行命令pipenv install来生成自己的虚拟环境。而Pipfile.lock文件用于保证包的完整性。

1.Pipfile文件

每次创建环境在当前目录下都会生成一个名为Pipfile文件,用来记录刚创建的环境信息。如果在当前目录下存在之前的Pipfile文件,新的Pipfile文件会将其覆盖。

Pipfile文件主要用来配置项目依赖的第三方工具、工具包的镜像源、Python解释器的版本等,该文件的示例如下:

# 主要用来配置包的下载网址
[[source]]
# 指定包的安装镜像源,一般使用国内的镜像来加快下载速度
url = "https://mirrors.aliyun.com/pypi/simple/"
verify_ssl = true
name = "pypi"
# 项目运行所需要依赖的第三方工具,即下载安装的工具包
[packages]
flask-authz ==='2.4.0'
# * 表示安装最新稳定版本
flask = '*'
# 开发依赖的工具包
[dev-packages] 
# 开发环境需要的包,不常用
# Python 解释器配置
[requires]
# 指定Python解释器的版本
python_version = "3.9"
2.Pipfile.lock文件

Pipfile.lock文件是通过哈希算法将包的名称、版本和依赖关系生成哈希值,可以保证包的完整性,锁定Python版本,便于以后项目发布使用固定的包。

在正常情况下,Pipfile.lock文件不会自动更新工具的版本,例如安装的requests库一开始是2.26.0版本,后来指定安装2.25.1版本,那么Pipfile文件会更新,但是Pipfile.lock文件不会更新,只有手动执行pipenv lock命令后才会更新。

Pipfile.lock文件保存了包的哈希值,这是确保生产环境和开发环境包信息一致的关键。当我们把项目从开发环境复制到生产环境,我们只需要执行pipenv install,而无须重新安装之前在开发环境中安装的包,这很省心。

1.4.6 pipenv安装依赖工具包

接下来,我们用pipenv安装requests库试一下,命令为pipenv install requests。pipenv安装依赖工具包成功如图1-15所示。

图1-15 pipenv安装依赖工具包成功

另外,pipenv install提供了--dev参数,用于区分需要部署到线上的开发包和只需要在测试环境中执行的包,这样就能明确不需要部署在线上的包,尽可能保证包干净。

提示

第一次安装包会比较慢,因为安装过程包含创建虚拟环境的过程。另外,如果使用默认安装源,大多数情况下会卡在锁定阶段,一般解决办法有两个。

(1)更改安装源,修改项目目录下的Pipfile文件中url后边的内容。pipenv本身就是基于pip的,所以也可以更换安装源。例如下面的Pipfile文件中使用阿里云提供的安装源:

[[source]]
url = "https://mirrors.aliyun.com/pypi/simple"
verify_ssl = true
name = "pypi"

(2)使用--skip-lock参数跳过锁定过程,锁定过程会比较费时,可以等真正完成项目开发要提交到仓库时再去锁定。

1.4.7 常用命令

一般通过命令pipenv -h可以看到pipenv的命令参数和命令示例,如图1-16和图1-17所示。

图1-16 pipenv的命令参数

图1-17 pipenv的命令示例

pipenv具体的使用方法为pipenv [OPTIONS] COMMAND [ARGS]...。其中,OPTIONS(操作参数)如表1-2所示。

表1-2 OPTIONS(操作参数)

pipenv可使用的命令如表1-3所示。

表1-3 pipenv可使用的命令

例如,进入(激活)虚拟环境,执行pipenv shell命令。虚拟环境创建好后,需要被激活才能在当前命令行中使用,可以理解为将当前命令行环境中PATH变量的值替换。此时pipenv会启动一个激活虚拟环境的子shell,然后我们会发现命令行提示符前添加了虚拟环境名,虚拟环境名为项目名。激活虚拟环境示例如图1-18所示。

图1-18 激活虚拟环境示例

在虚拟环境下,执行exit命令即可退出虚拟环境。所以,若要在虚拟环境中执行Python脚本,有如下两种方式。

第一种是直接执行命令pipenv run python test.py。

第二种是先激活虚拟环境,然后再运行脚本,命令如下:

pipenv shell
python test.py

提示

不要使用命令pip install。虽然在虚拟环境中也会安装对应的包,但是不会更新Pipfile文件和Pipfile.lock文件,不便于后续的环境迁移。

pipenv --rm只是把创建的虚拟环境删除了,但Pipfile文件和Pipfile.lock文件还存在。下次如果想要创建与项目名相同的虚拟环境,只要切换到原项目目录下执行命令pip install即可。

1.4.8 部署迁移虚拟环境

一般一个项目会创建一个目录,由于Python项目不需要编译,开发完成后,将项目目录拷贝到服务器上就可以完成部署了。但是,在项目开发过程中,我们会陆续安装和部署一些依赖工具,保证项目运行,要记住安装了哪些依赖不是件轻松的事。

1.以前的部署流程

使用pip提供的导出依赖工具名的功能,将环境中项目依赖的第三方工具名导出并导入requirements.txt文件。命令为pip freeze > requirements.txt。然后,上传到服务器,在服务器上依据requirements.txt文件安装工具包,命令为pip install -r requirements.txt。

值得注意的是,pip freeze命令并不是针对特定项目的,该命令导出的是所在Python环境中的所有第三方工具。如果一个Python环境中,创建了两个不同的项目,各自有不同的依赖,那么导出的依赖会是两个项目依赖的并集,虽然这对部署来说没有问题,但安装没必要的依赖不算是好事,后续可能出现包冲突的问题。

因此,在创建项目时,为其创建一个独立的Python虚拟环境是个好的编程习惯。

2.现在的部署流程

我们通过pipenv使用虚拟环境管理项目依赖,在开发环境完成开发后,如何构建生产环境呢?这时候需要使用Pipfile.lock文件。我们执行命令pipenv lock,把当前环境的模块锁定,执行命令后它会更新Pipfile.lock文件,该文件是用于生产环境的。然后,我们只需要把代码、Pipfile文件和Pipfile.lock文件放到生产环境,执行命令pipenv install,就可以创建和开发环境一样的环境了。Pipfile.lock文件记录了所有包和子包的明确版本,以完成确定的构建。如果要在另一个开发环境开发,则将代码和Pipfile文件复制过去,执行命令pipenv install --dev,将会安装包括dev对应的开发环境中的包。

我们之所以要在开发时养成创建和使用虚拟环境的好习惯,除了避免未来工具之间的冲突,还有一个重要的原因是方便部署迁移。因为虚拟环境是独立的,仅包含项目相关的依赖,所以部署的效率更高,风险更小。

requirements.txt文件的兼容

pipenv可以像virtualenv一样用命令生成requirements.txt文件。

# 将Pipfile文件和Pipfile.lock文件里面的工具名导出到requirements.txt文件
pipenv lock -r  > requirements.txt
# 通过requirements.txt文件进行安装
pipenv install -r requirements.txt

如果老项目一开始没有使用pipenv进行依赖管理,那么因为requirements.txt文件的完全兼容的特性,我们可以重新通过pipenv来管理项目依赖,只需要pipenv读取原有的最新的requirements.txt并重新生成依赖到Pipfile文件中即可。 R1OHpkII6fSS8PbagBXy6UXSvt1jiosjMphIEMiGg4UoLu5sEUYNskD7yNdsUrbE

点击中间区域
呼出菜单
上一章
目录
下一章
×