在某些python的开发项目中,或跑一些demo,例如tensorflow的demo,要求python3.5以上的版本,若原系统环境只有python2.7.5,显然无法满足测试环境。若为系统安装python3.5+,有些库又会造成版本冲突,因此需要使用python的虚拟环境工具来解决这些矛盾。当然也可采用python的docker镜像,使用一个镜像独立环境运行项目,但相比于python虚拟化工具来说,这种docker镜像显得有点重。
1、python虚拟工具介绍
目前有几种方式创建python的虚拟环境,在python3中有标准库venv,而第三方库例如virtualenv、virtualenvwrapper、pyenv,那么在项目或者说在实际开发里面,选哪种工具更为适合?
1.1 virtualenv
virtualenv 是目前较为常用的 python 虚拟环境配置工具。它不仅同时支持 python2 和 python3,而且可以为每个虚拟环境指定 python 解释器(要求系统已经安装了不同版本的python),并选择不继承基础版本的site-packages。
1.2 virtualenvwrapper
virtualenvwrapper是virtualenv的一个封装,目的是使后者更好用。virtualenv在使用中,每次得去虚拟环境所在目录下的 bin 目录下 source activate,也即当有多个虚拟环境时,得每次都去找对应的目录,virtualenvwrapper将所有的虚拟环境目录全都集中起来统一管理,避免每次开启虚拟环境时候的source 项目目录操作。
1.3 venv
Python 从3.3 版本开始,自带了一个虚拟环境 venv,在 PEP-405 中可以看到它的详细介绍。它的很多操作都和 virtualenv 类似。也支持linux和win。venv也有局限性,例如当前系统python版本为3.5,那么venv只能在当前安装的python3.5版本,不能创建其它Python 3.x的版本以及Python 2的环境。
1.4 pyenv
pyenv
主要用来安装、管理Python的版本及其虚拟环境,比如一个项目需要Python2.x,一个项目需要Python3.x。而virtualenv主要用来管理Python包的依赖。不同项目需要依赖的包版本不同,则需要使用虚拟环境。pyenv
通过系统修改环境变量来实现Python不同版本的切换。前面的三个工具都是用于虚拟环境切换,pyenv是 Python 版本环境切换工具,将这两套工具结合使用,可以完美解决 python 多版本环境的问题。具体实例在第4节给出。
2、使用virtualenv创建和管理虚拟环境
2.1 为多个python版本安装相应的pip
centos7.5默认没有pip包,因此需求手动安装,本文系统已经安装python2.7和python3.6。这里给出python2.7的pip安装和python3.6的pip3安装。
pip安装依赖setuptools,首先为python2和python3安装相应setuptools1
2
3
4
5
6
7
8
9
10[root@localhost local]# pwd
/usr/local
[root@localhost local]# wget https://files.pythonhosted.org/packages/ab/41/ab6ae1937191de0c9cbc115d0e91e335f268aa1cd85524c86e5970fdb68a/setuptools-42.0.0.zip
[root@localhost local]# unzip setuptools-42.0.0.zip
[root@localhost local] cd setuptools-42.0.0
注意这里的python命令是连接到python2.7,所以setuptools库只在python2.7环境生效
[root@localhost setuptools-42.0.0]# python2.7 setup.py install
给python3.6安装setuptools
[root@localhost setuptools-42.0.0]# python3.6 setup.py install
这里为何使用python2.7或者python3.6,因为如果想要构建更多python版本,其shell执行命令例如python3.5,python3.7则会显得清晰而不混乱。
为python2和python3安装相应pip,跟setuptools安装流程一致。
1 |
|
2.2 安装virtualenv
上面已经配置了python2.7环境和python3.6环境,virtualenv库无需在两种环境安装,这里安装到python2.7库下即可。
这里要注意:如果系统已经安装python3版本,且shell已经设定python命令是软链接到python3
1 | [root@localhost opt]# ls -al /usr/bin/python |
那么需要使用pip3安装 virtualenv,这样virtualenv库才会安装到python3的site-packages目录下,
如果shell已经设定python命令是软链接到python2
1 | [root@localhost opt]# ls -al /usr/bin/python |
那么需要使用pip安装 virtualenv,这样virtualenv库才会安装到python2的site-packages目录下。
若不按照上述的环境情况,安装virtualenv,会出现以下情况
1 | [root@localhost opt]# virtualenv -v |
当前python是软链到python3,而pip安装的virtualenv是在python2.7路径下,python3并没有virtualenv这个库
1 | [root@localhost opt]# python3 |
virtualenv在python2.7路径下
1 | [root@localhost opt]# python |
解决办法:将当前python命令软链到python21
[root@localhost opt]# ln -s /usr/bin/python2 /usr/bin/python
2.3、virtualenv创建虚拟环境
在/opt/pvenv_test目录下,创建一个使用python2.7解释器、且独立安装第三方库的运行环境、名字为crmapp的python2.7项目环境
1 | [root@localhost pvenv_test]# virtualenv --python=python2.7 --no-site-packages crmapp |
在/opt/pvenv_test目录下,创建一个使用python3.6解释器、且独立安装第三方库的运行环境、名字为djwebsocket的python3.6项目环境
1 | [root@localhost pvenv_test]# virtualenv --python=python3.6 --no-site-packages djwebsocket |
这里的 —python=python3 其实就是 /usr/bin/python3对于的python3.6解释器
3、pyenv终极python版本和虚拟化环境管理工具
有关virtualenvwrapper或者venv的用法,因内容较为简单,这里不再讨论,本文推荐使用pyenv管理任意基于python项目的虚拟环境。
3.1 pyenv的设计原理
pyenv
主要用来管理Python的版本,比如一个项目需要Python2.x,一个项目需要Python3.x。而virtualenv主要用来管理Python包的依赖。不同项目需要依赖的包版本不同,则需要使用虚拟环境。
pyenv
通过系统修改环境变量来实现Python不同版本的切换。而vitualenv通过Python包安装到一个目录来作为Python虚拟包环境,通过切换目录来实现不同包环境间的切换。
pyenv
的设计巧妙的地方在于,在PATH 的最前面插入了一个垫片路径(shims):~/.pyenv/shims:/usr/local/bin:/usr/bin:/bin。所有对 Python 可执行文件的查找都会首先被这个 shims 路径截获,从而使后方的系统路径失效。
对于系统环境变量 PATH ,里面包含了一串由冒号分隔的路径,例如 /usr/local/bin:/usr/bin:/bin。每当在系统中执行一个命令时,例如 python 或 pip,操作系统就会在 PATH 的所有路径中从左至右依次寻找对应的命令。因为是依次寻找,因此排在左边的路径具有更高的优先级。在PATH 最前面插入一个 $(pyenv root)/shims
目录,$(pyenv root)/shims
目录里包含名称为python以及pip等可执行脚本文件;当用户执行python或pip命令时,根据查找优先级,系统会优先执行shims目录中的同名脚本。pyenv 正是通过这些脚本,来灵活地切换至我们所需的Python版本。
需要手工去查找python版本的所在路径,如果有多个版本,这种手工管理显得有点繁琐。
3.2 安装pyenv
pyenv安装python需要依赖底层的系统库
1 | [root@localhost bin] yum install -y gcc make patch gdbm-devel openssl-devel sqlite-devel readline-devel zlib-devel bzip2-devel ncurses-devel libffi-devel |
若系统库不全,pyenv安装python后,会有如下提示:
1 | [root@localhost bin]# pyenv install 3.7.5 |
有三个warning提示,系统环境缺少 bzip2、readline、SQLite3。
下载pyenv1
wget git clone https://github.com/pyenv/pyenv.git ~/.pyenv
将PYENV_ROOT
和pyenv init
加入bash的~/.bashrc
(或zsh的~/.zshrc
)
1 | echo 'export PATH=~/.pyenv/bin:$PATH' >> ~/.bashrc |
激活pyenv
(zsh为~/.zshrc
)
1 | source ~/.bashrc |
指定python版本在线安装
1 | [root@localhost bin]# pyenv install 3.7.5 |
常用命令1
2
3
4
5
6
7
8pyenv install --list # 列出可安装版本
pyenv install <version> # 安装对应版本
pyenv uninstall <version> # 卸载对应版本的python
pyenv uninstall <venv name> # 删除指定虚拟环境
pyenv install -v <version> # 安装对应版本,若发生错误,可以显示详细的错误信息
pyenv versions # 显示当前使用的python版本
pyenv which python # 显示当前python安装路径
pyenv global <version> # 设置默认Python版本
3.3pyenv离线安装python各版本
pyenv自动去官网拉取python安装包,如果要为离线服务器安装,则只需在.pyenv
创建cache目录,将指定版本的python安装包放在该目录。
python安装包下载地址:https://www.python.org/ftp/python/
只需下载Python-*.tar.xz 即可
1 | [root@localhost cache]# pwd |
3.4 使用多个python版本
1 | pyenv设为系统原有python版本: |
pyenv在python版本方面得心应手。
3.5 pyenv结合/pyenv-virtualenv实现灵活的虚拟环境管理
在第3.2章节介绍了virtualenv用于管理pip包的虚拟环境,virtualenv有个不足地方是:系统需已安装多个python版本,一般会通过手工安装,也即编译时指定不同路径,避免冲突。pyenv作者同时也开发pyenv-virtualenv的工具,跟virtualenv功能一致,也是用于管理pip包以及虚拟环境,结合pyenv,可以实现任意python版本以及pip包环境的切换以及使用,高效提高个人开发效率。
pyenv-virtualenv放在.pyenv/plugins 这个插件目录下
1 | [root@localhost plugins]# pwd |
创建python3.7.5版本、虚拟环境名为tf375
1 | [root@localhost opt]# pyenv virtualenv 3.7.5 tf375 |
激活tf375环境,pyenv支持对环境名的自动补全,非常方便,pip包默认不继承系统包。
1 | [root@localhost opt]# pyenv activate tf375 |
创建python3.6.5版本、虚拟环境名为spk的pyspark开发环境1
2
3
4
5[root@localhost opt]# pyenv virtualenv 3.6.5 pyspark_proj
[root@localhost opt]# pyenv activate pyspark_proj
(pyspark_proj) [root@localhost opt]# pip list
pip (9.0.3)
setuptools (39.0.1)