虚拟开发环境搭建
本节讲解了什么是虚拟开发环境以及虚拟开发环境的功能,它用于解决版本依赖的问题,讲解了如何使用 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. 小结
本节讲解了什么是虚拟开发环境以及虚拟开发环境的功能,使用思维导图总结如下: