Python多版本管理工具pyenv及环境隔离工具virtualenv

Python可以使用pyenv管理并切换同一系统下的多个python解释器版本,pyenv支持非常多的python版本,也包括各大知名python的衍生版,如anaconda。而virtualenv可以为每个文件夹指定一个特定的python环境,各文件夹的python环境独立,共用一个统一的python基础版本,可以用于隔离不同项目的包环境,及包版本。当然pyenv也支持为不同的文件夹指定不同的python版本,但不同文件夹下的同一个python版本共用环境,所以pyenv与virtualenv结合使用,便可以实现任意版本下的环境隔离随意切换,pyenv自带virtualenv插件。
可以简单理解如下:

  • pyenv 实现Python版本管理
  • virtualenv 实现Python环境隔离

我的系统环境为Ubuntu16.04.2

安装pyenv

安装依赖

其实pyenv是个脚本,并不需要安装它的依赖,但pyenv安装的python为通过下载相应的python源码,然后进行编译,所以需要安装相应的编译依赖:

1
2
3
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev

pyenv安装

官方提供了自动安装脚本来安装pyenv,直接运行即可:

1
curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash

pyenv会被安装在用户根目录的~/.pyenv路径,以后通过pyenv安装的所以python版本也都将在该目录中。上述命令会在用户的.bashrc中添加以下内容:

1
2
3
4
5
# pyenv
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

卸载pyenv也只需要删除目录~/.pyenv以及相应的.bashrc中的内容即可

更新pyenv的命令为:

1
pyenv update

安装完成之后通过pyenv --version,查看其版本

pyenv使用

pyenv的核心命令,以及常用的核心命令用法如下:
pyenv commands
查看pyenv所支持的所有命令:

pyenv version
查看当前激活的python版本及相关信息
输出:

1
2
$ pyenv version
3.6.1 (set by /home/blueyi/tpyenv/.python-version)

pyenv versions
查看系统中的所有python版本,当前使用的版本使用*标记
输出如下:

1
2
3
4
$ pyenv versions
system
2.7.13
* 3.6.1 (set by /home/blueyi/tpyenv/.python-version)

pyenv which
查看指定python的完全路径
如:

1
2
$ pyenv which python3
/home/blueyi/.pyenv/versions/3.6.1/bin/python3

注意command必须是shell命令

pyenv whence [–path]
列出包含给定命令的所有python版本
如:

1
2
3
$ pyenv whence pip
2.7.13
3.6.1

pyenv install
安装指定版本的python
该命令后面可以跟一些参数,或者版本号,可以通过以下命令查看所有支持的python版本:

1
pyenv install -l|--list

安装python3.6.1:

1
pyenv install 3.6.1 -v

安装miniconda3-4.3.11:

1
pyenv install miniconda3-4.3.11

加上参数-v,用于显示详细安装过程
安装完成之后可以通过以下命令重建shims,以便让pyenv能够找到相应的版本及包,通过安装新版本的python以及包之后都应该运行一次:

1
pyenv rehash

安装完成之后可以通过上面的pyenv versions来查看系统中的所有python版本
安装的python在路径~/.pyenv/versions/

1
2
$ ls ~/.pyenv/versions/
2.7.13 3.6.1

pyenv uninstall [-f|–force]
卸载指定的版本

pyenv local
为当前目录设置指定的python版本,可以创建一个文件夹,在其中测试:

1
pyenv local 3.6.1

该命令会在当前文件夹下创建文件.python-version,并将相应的版本号写入其中,该版本号将覆盖全局版本。
如果local后面不跟版本号,则会显示当前局部版本信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ pyenv local
3.6.1

$ cat .python-version
3.6.1

$ python --version
Python 3.6.1

$ pyenv versions
system
2.7.13
* 3.6.1 (set by /home/blueyi/tpyenv/.python-version)

$ pyenv global
system

从上述命令的输出中可以看出,我的当前目录python版本被设置为了3.6.1,而全局的python版本使用的是系统自带的版本(2.7.12),同时我又安装了2.7.13版本。
取消当前的局部版本设置:

1
pyenv local --unset

local后面也可以接多个版本号,优先级按命令后面的顺序排列(摘自官方文档):

1
2
3
4
5
6
7
8
9
10
11
$ pyenv local 2.7.6 3.3.3
$ pyenv versions
system
* 2.7.6 (set by /Users/yyuu/path/to/project/.python-version)
* 3.3.3 (set by /Users/yyuu/path/to/project/.python-version)
$ python --version
Python 2.7.6
$ python2.7 --version
Python 2.7.6
$ python3.3 --version
Python 3.3.3

pyenv global
与local命令类似,只是它用于设置全局的python版本,该版本号存储在文件~/.pyenv/version中,该版本会被局部版本号或者环境变量PYENV_VERSION指定的版本号覆盖。

1
2
3
4
5
$ python --version
Python 2.7.12
$ pyenv global 2.7.13
$ python --version
Python 2.7.13

global后面不接版本号只显示当前的全局版本

global后面也可以接多个版本,与local功能类似:

1
2
3
4
5
6
7
8
9
10
11
$ pyenv global 2.7.6 3.3.3
$ pyenv versions
system
* 2.7.6 (set by /Users/yyuu/.pyenv/version)
* 3.3.3 (set by /Users/yyuu/.pyenv/version)
$ python --version
Python 2.7.6
$ python2.7 --version
Python 2.7.6
$ python3.3 --version
Python 3.3.3

pyenv shell
通过设置环境变量PYENV_VERSION来指定当前shell环境的python版本,该版本会覆盖局部版本和全局版本。

1
pyenv shell pypy-2.2.1

相当于:export PYENV_VERSION=pypy-2.2.1

取消当前shell环境设置的python版本:

1
pyenv shell --unset

同样可以为shell命令指定多个版本号:

1
2
3
4
5
6
7
8
9
10
11
$ pyenv shell 2.7.6 3.3.3
$ pyenv versions
system
* 2.7.6 (set by PYENV_VERSION environment variable)
* 3.3.3 (set by PYENV_VERSION environment variable)
$ python --version
Python 2.7.6
$ python2.7 --version
Python 2.7.6
$ python3.3 --version
Python 3.3.3

virtualenv使用

pyenv将virtualenv以一个插件的形式包含在pyenv中,pyenv的插件路径为:

1
2
$ ls ~/.pyenv/plugins/
pyenv-doctor pyenv-installer pyenv-update pyenv-virtualenv pyenv-which-ext python-build

此处只简单介绍virtualenv用于python环境隔离的用法,更多virtualenv功能可以参见其官方文档。
virtualenv的使用方法为首先创建虚拟环境,然后激活虚拟环境。
创建虚拟环境

1
pyenv virtualenv [-f|--force] [VIRTUALENV_OPTIONS] [version] <virtualenv-name>

例如创建一个以python2.7.13为基础版,名为mypy2.7.13的虚拟环境:

1
pyenv virtualenv 2.7.13 mypy2.7.13

如果不指定版本,默认使用当前环境的python版本

列出当前所有的虚拟环境

1
2
3
$ pyenv virtualenvs
2.7.13/envs/mypy2.7.13 (created from /home/blueyi/.pyenv/versions/2.7.13)
mypy2.7.13 (created from /home/blueyi/.pyenv/versions/2.7.13)

也可以通过pyenv versions来查看:

1
2
3
4
5
6
7
$ pyenv versions
* system (set by /home/blueyi/.pyenv/version)
2.7.13
2.7.13/envs/mypy2.7.13
3.5.0
3.6.1
mypy2.7.13

所以也可以为指定文件夹通过pyenv local来指定其版本为当前的虚拟环境

激活指定的虚拟环境

1
$ pyenv activate mypy2.7.13

激活之后,terminal的前面会有(mypy2.7.13)标识,此时通过pip安装包,以及相关的操作都只会修改该虚拟环境,对原python环境不会有任何影响。激活之后,直到手动退出该虚拟环境,或该shell之前都有效。而如果通过pyenv local指定局部环境为该虚拟环境的话,退出该文件夹即失效,再次进入又会自动生效。

退出当前虚拟环境

1
pyenv deactivate

删除指定的虚拟环境

1
pyenv uninstall mypy2.7.13

pyenv配合其插件pyenv-virtualenv用于开发及测试,非常方便,再也不用怕环境被搞乱了。

参考

1.pyenv
2.pyenv wiki
3.virtualenv
4.https://virtualenv.pypa.io