虚拟开发环境搭建

本节讲解了什么是虚拟开发环境以及虚拟开发环境的功能,它用于解决版本依赖的问题,讲解了如何使用 virtualenv 命令创建、激活一个虚拟开发环境。

1. 什么是虚拟开发环境

虚拟开发环境是一个隔离的运行环境,每个运行环境中包含有一套独立的组件:Python 解释器、各种第三方包。每个运行环境中包含的组件是私有的、不共享的,因此运行环境之间是隔离的。

使用 Python 开发一个项目,需要安装各种第三方包,项目有可能依赖特定版本的第三方包。例如,项目 A 依赖 3.5.3 版本的 redis 包,而项目 B 依赖 3.0.0 版本的 redis 包。通过为项目 A 和项目 B 分别设置一个虚拟开发环境,项目 A 的虚拟开发环境中包含 3.5.3 版本的 redis 包,项目 B 的虚拟开发环境中包含 3.0.0 版本的 redis 包,从而解决了第三方包的版本依赖问题。

2. 不同版本的包带来的问题

2.1 不同版本的包

默认情况下,使用 pip3 安装包时,会安装包的最新版本,例如:

$ sudo pip3 install redis
Collecting redis
  Downloading redis-3.5.3-py2.py3-none-any.whl (61 kB)
     |████████████████████████████████| 72 kB 126 kB/s
Installing collected packages: redis
Successfully installed redis-3.5.3

可以看到使用 pip 安装 redis 包会默认安装最新的 3.5.3 版本。

但某些情况下,出于兼容性的考虑,程序只能使用特定版本的 redis 包,需要使用 pip3 安装包的特定版本,例如:

$ sudo pip3 install redis==3.0.0
Collecting redis==3.0.0
  Downloading redis-3.0.0-py2.py3-none-any.whl (61 kB)
     |████████████████████████████████| 61 kB 137 kB/s
Installing collected packages: redis
Successfully installed redis-3.0.0

指定选项 redis==3.0.0,会安装 redis 3.0.0 版本。

2.2 带来的问题

因为应用程序可能依赖特定版本的包,当系统中存在多个项目时,可能会出现冲突。例如:

  • 有两个项目:项目 A 和 项目 B;
  • 项目 A 依赖于 redis-3.5.3;
  • 项目 B 依赖于 redis-3.0.0。

如果,需要同时进行两个项目的开发,则必须:

  • 开发项目 A 时,卸载系统中现有的 redis 包,安装 redis-3.5.3;
  • 开发项目 B 时,卸载系统中现有的 redis 包,安装 redis-3.0.0。

在两个项目之间切换时,用户需要频繁的安装和卸载 redis 包,显然是很不合理的。

那么,这种不合理应该如何解决呢?

在 Python 开发中有个神器叫做 virtual 就是专门用来解决问题的,下面我们就来看下 virtual 这个神器到底神在哪里?

3. 使用 virtual 解决冲突

上面我们说到,不同的项目依赖不同的包很有可能造成项目冲突问题,而 virtual 则正是为了解决这个问题而诞生的:

virtualenv 命令可以创建一个隔离的运行环境:

  • 每个运行环境中包含有一套组件:Python 解释器、各种第三方包;
  • 每个运行环境中包含的组件是私有的、不共享的;
  • 因此运行环境之间是隔离的。

针对 2.2 小节中项目依赖的问题,使用 virtualenv 的解决方法如下图所示:

图片描述

使用 virtualenv 为项目 A 创建一个隔离环境,隔离环境中包括 python 解释器和 redis-3.5.3。使用 virtualenv 为项目 B 创建一个隔离环境,隔离环境中包括 python 解释器和 redis-3.0.0。

如果,需要同时进行两个项目的开发,则开发项目 A 时,进入项目 A 的虚拟环境,开发项目 B 时,进入项目 B 的虚拟环境,也可以同时打开两个终端,分别进行项目 A 和项目 B 的虚拟环境,同时进行两者的项目开发。每一个虚拟环境中的 Python 版本,包版本互不影响,自然完美解决了冲突问题。

4. virtualenv 的使用

既然知道了有 virtualenv 这个神器,那么我们就要把它用在我们的实际开发中去,下面我们就演示一下 virtualenv 如何使用:

4.1 安装 virtualenv

在 linux 下,使用 apt 命令安装 virtualenv:

$ sudo apt install virtualenv

或者,使用 pip3 命令安装 virtualenv:

$ sudo pip3 install virtualenv

4.2 安装一个纯净的虚拟环境

假设用户是 guest,当前目录是 /home/guest:

$ pwd
/home/guest

现在希望创建一个虚拟环境 pure,将虚拟环境的 python 和第三方包存放在 /home/guest/pure 目录下:

$ virtualenv -p python3 --no-site-packages pure
Already using interpreter /usr/bin/python3
Using base prefix '/usr'
New python executable in /home/guest/pure/bin/python3
Also creating executable in /home/guest/pure/bin/python
Installing setuptools, pkg_resources, pip, wheel...done.

选项 -p python3,表示 Python 有两个版本 python2 和 python3,指定虚拟环境中的 python 版本为 python3;选项 --no-site-packages,表示不安装任何所第三方包,得到了一个不带任何第三方包的 “纯净” 的 Python 运行环境。选项 pure,表示将虚拟环境的 python 和第三方包存放在 pure 目录下,注意,创建虚拟环境后,不可以再移动虚拟环境目录 pure 的位置。

4.3 虚拟环境 pure 的内容

使用 virtualenv 命令创建虚拟环境,创建的目录 pure 中的内容如下:

图片描述

目录 pure 中包含的文件功能如下表所示:

文件名 功能
bin 存放 python3、pip3 等程序
lib 存放第三方库
bin/activate 进入虚拟环境的脚本

4.4 进入虚拟环境

$ source pure/bin/activate
  • bin/activate 是进行虚拟化环境的脚本;
  • 使用 source 命令执行 bin/activate 脚本。

bin/activate 执行成功后,shell 的命令提示符变为:

(pure) $
  • 原先的提示符是 $,现在是(pure) $;
  • 提示用户现在处于 pure 环境中,此时输入 python3;
  • 执行的 python3 命令是 pure/bin/python3;
  • 而不是系统的 /usr/bin/python3 。

4.5 在虚拟环境中安装指定版本的包

在 pure 环境中,安装指定版本的 redis:

(pure) $ pip3 install redis==3.0.0
Collecting redis==3.0.0
  Downloading redis-3.0.0-py2.py3-none-any.whl (61 kB)
     |████████████████████████████████| 61 kB 137 kB/s
Installing collected packages: redis
Successfully installed redis-3.0.0

版本为 3.0.0 的 redis 会被安装到 pure 目录下:

(pure) $ ls pure/lib/python3.6/site-packages
easy_install.py       pkg_resources-0.0.0.dist-info  setuptools
pip                   __pycache__                    setuptools-49.2.0.dist-info
pip-20.1.1.dist-info  redis                          wheel
pkg_resources         redis-3.0.0.dist-info          wheel-0.34.2.dist-info

在 pure 环境下所有的第三方包被安装到 pure/lib/python3.6/site-packages 目录中去,目录 redis-3.0.0.dist-info 表示当前安装在 pure 环境中的 redis 的版本是 3.0.0。

4.6 退出虚拟环境

在虚拟环境中,执行 deactivate,会退出虚拟环境:

(pure) $ deactivate

bin/deactivate 执行成功后,shell 的命令提示符变为:

$
  • 原先的提示符是 (pure) $,现在是 $;
  • 提示用户现在处于系统环境中,此时输入 python3;
  • 执行的 python3 命令是系统的 /usr/bin/python3;
  • 而不是 pure/bin/python3。

5. 小结

本节讲解了什么是虚拟开发环境以及虚拟开发环境的功能,使用思维导图总结如下:

图片描述