linux下python项目开发独立环境之virturlenv及virtualenvwraper

在使用 Python 开发的过程中,工程一多,难免会碰到不同的工程依赖不同版本的库的问题;亦或者是在开发过程中不想让物理环境里充斥各种各样的库,引发未来的依赖灾难。此时,我们需要对于不同的工程使用不同的虚拟环境来保持开发环境以及宿主环境的清洁。

这里,就要隆重介绍 virtualenv,一个可以帮助我们管理不同 Python 环境的绝好工具。virtualenv 可以在系统中建立多个不同并且相互不干扰的虚拟环境。

安装virtualenv

在开发Python应用程序的时候,系统安装的Python3只有一个版本:3.6。所有第三方的包都会被pip安装到Python3site-packages目录下。

如果我们要同时开发多个应用程序,那这些应用程序都会共用一个Python,就是安装在系统的Python 3。如果应用A需要jinja 2.7,而应用B需要jinja 2.6怎么办?

这种情况下,每个应用可能需要各自拥有一套“独立”的Python运行环境。virtualenv就是用来为一个应用创建一套“隔离”的Python运行环境。

virtualenv原理

将系统Python复制一份到virtualenv的环境,用命令source venv/bin/activate进入一个virtualenv环境时,virtualenv会修改相关环境变量,让命令pythonpip均指向当前的virtualenv环境。

使用pip安装virtualenv

1
pip3 install virtualenv

创建虚拟运行环境

1
2
3
4
5
6
7
8
9
# 创建python虚拟环境目录
mkdir /www/pyenv
cd /www/pyenv
# 创建一个python2的独立虚拟环境
virtualenv --no-site-packages --python=python2 py2
# 创建一个python3的独立虚拟环境
virtualenv --no-site-packages --python=python3 py3


运行虚拟环境

运行py2虚拟环境

1
2
# 读取进入python2独立虚拟环境
source py2/bin/activate
1
2
3
# 查看py2虚拟环境中pyhon版本
(py2) root@Tony-PC:/www/sitepy/py2# python -V
Python 2.7.15
1
2
3
4
5
# 查看py2虚拟环境中python位置和pip位置
(py2) root@Tony-PC:/www/sitepy/py2# which python
/www/envpy/py2/bin/python
(py2) root@Tony-PC:/www/sitepy/py2# which pip
/www/envpy/py2/bin/pip

运行py3虚拟环境

1
2
# 读取进入python3独立虚拟环境
source py3/bin/activate
1
2
3
# 查看py3虚拟环境中pyhon版本
(py3) root@Tony-PC:/www/sitepy/py2# python -V
Python 3.6.5
1
2
3
4
5
# 查看py3虚拟环境中python位置和pip位置
(py3) root@Tony-PC:/www/sitepy/py2# which python
/www/envpy/py3/bin/python
(py3) root@Tony-PC:/www/sitepy/py2# which pip
/www/envpy/py3/bin/pip

安装django

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# py2环境安装django
(py2) root@Tony-PC:/www/sitepy/py2# pip install django
# 查看py2环境已安装的pip包
(py2) root@Tony-PC:/www/sitepy/py2# pip list
# 显示结果
Package Version
---------- -------
Django 1.11.23
pip 19.2.1
pytz 2019.2
setuptools 41.0.1
wheel 0.33.4


# py3环境安装django
(py3) root@Tony-PC:/www/sitepy/py2# pip install django
# 查看py3环境已安装的pip包
(py3) root@Tony-PC:/www/sitepy/py2# pip list
# 显示结果
Package Version
---------- -------
Django 2.2.4
pip 19.2.1
pytz 2019.2
setuptools 41.0.1
wheel 0.33.4

创建django项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 进入网站目录
(py2) root@Tony-PC:/www#cd /www/sitepy
(py3) root@Tony-PC:/wwwcd /www/sitepy

# 创建py2环境的django项目
(py2) root@Tony-PC:/www/sitepy#django-admin startproject py2
# 进入py2项目目录
(py2) root@Tony-PC:/www/sitepy#cd py2
# 创建py2项目应用
(py2) root@Tony-PC:/www/sitepy/py2#django-admin startap app01
# 修改settings.py
(py2) root@Tony-PC:/www/sitepy/py2#vim py2/settings.py
# 将其中的allowed_host修改为['*']

# 创建py3环境的django项目
(py3) root@Tony-PC:/www/sitepy#django-admin startproject py3
# 进入py3项目目录
(py3) root@Tony-PC:/www/sitepy#cd py3
# 创建py3项目应用
(py3) root@Tony-PC:/www/sitepy/py3#django-admin startap app01

# 修改settings.py
(py3) root@Tony-PC:/www/sitepy/py3#vim py3/settings.py
# 将其中的allowed_host修改为['*']

运行django

1
2
3
4
5
# py2环境下运行py2网站项目
(py2) root@Tony-PC:/www/sitepy/py2#python manage.py runserver 0.0.0.0:8001

# py3环境下运行py3网站项目
(py3) root@Tony-PC:/www/sitepy/py3#python manage.py runserver 0.0.0.0:8002

查看结果

访问:127.0.0.1:8001

效果如下:

访问:127.0.0.1:8002

效果如下:

完美,两个网站在两个版本的python环境下跑起来了

退出虚拟环境

1
deactivate

开发一致性

1.假设我们在本地开发环境,准备好了项目+依赖包环境
2.现在需要将项目上传至服务器,上线发布
3.那么就要保证服务器的python环境一致性

解决方案

  1. 通过命令保证环境的一致性,导出当前python环境的包

    1
    2
    # 将py3环境依赖包列表导出到requirements.txt文件
    (py3) root@Tony-PC:/www/pyenv/py3#pip freeze > requirements.txt

    这将会创建一个 requirements.txt 文件,其中包含了当前环境中所有包及 各自的版本的简单列表。可以使用 “pip list”在不产生requirements文件的情况下, 查看已安装包的列表。

  2. 上传至服务器后,在服务器下创建virtualenv,在venv中导入项目所需的模块依赖

    1
    pip3 install -r requirements.txt

virtualenvwraper安装与使用

virtualenv 的一个最大的缺点就是:

每次开启虚拟环境之前要去虚拟环境所在目录下的 bin 目录下 source 一下 activate,这就需要我们记住每个虚拟环境所在的目录。

并且还有可能你忘记了虚拟环境放在哪。。。

  • 一种可行的解决方案是,将所有的虚拟环境目录全都集中起来,例如/opt/all_venv/,并且针对不同的目录做不同的事。
  • 使用virtualenvwrapper管理你的虚拟环境(virtualenv),其实他就是统一管理虚拟环境的目录,并且省去了source的步骤。

安装virtualenvwrapper

1
pip3 install virtualenvwrapper

设置环境变量

设置Linux的环境变量

设置Linux的环境变量,每次启动就加载virtualenvwrapper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
把下面两行代码添加到 ~/.bashrc文件中
打开文件
vim ~/.bashrc # vim编辑用户家目录下的.bashrc文件,这个文件是用户在登录的时候,就读取这个文件

# export 是读取shell命令的作用
# 这些变量根据你自己的绝对路径环境修改
export WORKON_HOME=~/Envs #设置virtualenv的统一管理目录
export VIRTUALENVWRAPPER_VIRTUALENV_ARGS='--no-site-packages' #添加virtualenvwrapper的参数,生成干净隔绝的环境
export VIRTUALENVWRAPPER_PYTHON=/opt/python347/bin/python3 #指定python解释器

#执行virtualenvwrapper安装脚本
source /opt/python34/bin/virtualenvwrapper.sh
读取文件,使得生效,此时已经可以使用virtalenvwrapper
source ~/.bashrc

设置Mac的环境变量

mac下的环境变量设置与linux稍有不同,至少本人安装的时候没有在家目录找到.bashrc文件,mac下是.bash_profile。

我们假设我们创建的虚拟环境统一目录还是~/Envs

我们要找下我们python解释器的位置,还要找下virtualenvwrapper安装脚本

1
2
3
4
Tony-iMac:~ tony$ which python3
/usr/local/bin/python3
Tony-iMac:~ tony$ which virtualenvwrapper.sh
/usr/local/bin/virtualenvwrapper.sh

都知道路径了我们才好配置环境变量

1
2
# 打开文件
vim ~/.bash_profile # vim编辑用户家目录下的.bashrc文件,这个文件是用户在登录的时候,就读取这个文件

然后把下面代码添加到 ~/.bash_profile

1
2
3
4
5
6
7
8
9
# export 是读取shell命令的作用
# 这些变量根据你自己的绝对路径环境修改
export WORKON_HOME=~/Envs #设置virtualenv的统一管理目录
export VIRTUALENVWRAPPER_VIRTUALENV_ARGS='--no-site-packages' #添加virtualenvwrapper的参数,生成干净隔绝的环境
export VIRTUALENVWRAPPER_PYTHON=/usr/local/bin/python3 #指定python解释器

#执行virtualenvwrapper安装脚本
source /usr/local/bin/virtualenvwrapper.sh

读取文件,使得生效,此时已经可以使用virtalenvwrapper

1
source ~/.bash_profile

基本使用virtualenvwrapper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
创建一个虚拟环境:
$ mkvirtualenv my_django115
这会在 ~/Envs 中创建 my_django115 文件夹。

在虚拟环境上工作:激活虚拟环境my_django115
$ workon my_django115


再创建一个新的虚拟环境
$ mkvirtualenv my_django2

virtualenvwrapper 提供环境名字的tab补全功能。
当有很多环境, 并且很难记住它们的名字时,这就显得很有用。
workon还可以任意停止你当前的环境,可以在多个虚拟环境中来回切换
workon django1.15

workon django2.0

也可以手动停止虚拟环境
deactivate

删除虚拟环境,需要先退出虚拟环境
rmvirtualenv my_django115

常用其他命令

1
2
3
4
5
6
7
8
9
10
lsvirtualenv
列举所有的环境。
cdvirtualenv
导航到当前激活的虚拟环境的目录中,比如说这样您就能够浏览它的 site-packages
cdsitepackages
和上面的类似,但是是直接进入到 site-packages 目录中。
lssitepackages
显示 site-packages 目录中的内容。

完整官网介绍:https://virtualenvwrapper.readthedocs.io/en/latest/command_ref.html