Python多版本管理和虚拟环境维护(pyenv, pyenv-virtualenv)
2017-02-19
前言
需求
在日常开发的过程中经常会遇到以下场景:
- 系统预装Python是2.6,项目需要Python2.7中的新特性
- 由于python的版本割裂, Python3 和 Python2想要共存
- 不通项目对于同一个依赖包的版本要求不同,希望基于项目的环境独立
virtualenv, virtualenvwrapper等工具解决了上述问题中一的部分,也有着自身局限和不够优雅的地方,例如,将不同的 $PATH 植入不同的shell这种高耦合的工作方式。
本篇的主题pyenv可以帮助你以更pythonic的方式管理多个版本python,创建和维护不同的虚拟环境, 并提供方便的切换方法。 pyenv受启发于ruby环境管理工具rbenv
原理
pyenv在$PATH的最前面插入了一个垫片路径(shims):~/.pyenv/shims:/usr/local/bin:/usr/bin:/bin。所有对 Python 可执行文件的查找都会首先被这个 shims 路径截获,从而架空了后面的系统路径。
安装
安装包依赖(编译python)
- Debian/Ubuntu
apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils
- macOS
brew install openssl readline xz
- CentOS/Fedora
yum install gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel
安装pyenv
1. 获取源文件
安装工具(推荐)
- macOS
brew update && brew install pyenv
- Linux
curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash
手动
选择安装到$HOME/.pyenv目录(但你可以在某处安装其他)。
$ cd && git clone git://github.com/yyuu/pyenv.git .pyenv
2. 配置环境变量
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
shell 配置文件(~/.bash_profile)依不同 Linux 而需作修改
- ~/.bash_profile (General)
- ~/.zshenv (Zsh)
- ~/.bashrc (Ubuntu)
3. 重启shell生效
exec $SHELL
使用
安装/卸载某个版本的python
可以先查看一下有哪些版本的python 可以安装
pyenv install --list
Available versions:
2.1.3
2.2.3
2.3.7
2.4
...
2.7.12
安装
安装文件很大, 如果由于网络的问题,总是连接中断或者下载很久导致安装失败。此时可以先从官方网站下载安装包,然后放在$PYENV_ROOT/cache文件夹中(该目录默认不存在,用户要自行新建),注意,从官网下载的文件后缀名需要由xxx.tgz
改为xxx.tar.gz
。然后在pyenv install 此版本,pyenv会自动先从此文件夹中搜索
pyenv install -v 2.7.1
卸载
pyenv uninstall 2.7.1
显示已安装python版本
*表示当前的python版本 system 代表当前系统的python版本
pyenv versions
system (set by /root/.pyenv/version)
2.5.6
2.6.8
*3.3.3
jython-2.5.3
pypy-2.2.1
不同版本的python切换
pyenv global
设置全局的 Python 版本,通过将版本号写入 ~/.pyenv/version 文件的方式。
pyenv global 3.4.0 ( ~/.pyenv/version )
pyenv local
设置面向程序的本地版本,通过将版本号写入当前目录下的 .python-version 文件的方式。通过这种方式设置的 Python 版本优先级较 global 高。pyenv 会从当前目录开始向上逐级查找 .python-version 文件,直到根目录为止。若找不到,就用 global 版本。
pyenv local 2.7.3 ( /usrl/local/project/.python-version )
pyenv shell
设置面向 shell 的 Python 版本,通过设置当前 shell 的 PYENV_VERSION 环境变量的方式。这个版本的优先级比 local 和 global 都要高。–unset 参数可以用于取消当前 shell 设定的版本。
pyenv shell pypy-2.2.1 ( $PYENV_VERSION )
pyenv shell --unset
切换后python版本确认
$ python -V
Python 2.7.10
显示当前pyenv使用的环境
$ pyenv version
三种可能的输出
-
system (set by /usr/local/var/pyenv/version) # global
-
2.7.11 (set by /usrl/local/project/.python-version) # local
-
3.5.2 (set by PYENV_VERSION environment variable) # shell
pyenv-virtualenv 维护虚拟环境
pyenv virtualenv是pyenv的插件,为Linux系统上的Python virtualenvs提供pyenv virtualenv命令。使用起来非常直观简单
pyenv-virtualenv插件项目主页:https://github.com/yyuu/pyenv-virtualenv
配置
目前pyenv-virtualenv已经包含在pyenv插件中, 无需手动安装,可以直接使用。需要注意的是需要执行如下命令,使配置生效
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bash_profile
source ~/.bash_profile
创建/删除虚拟环境
pyenv virtualenv orignal-version target-name
pyenv virtualenv 3.5.2 env352
pyenv virtualenv-delete env352
上面创建了一个名为env352 的python虚拟环境,这个环境的真实目录位于:~/.pyenv/versions/
切换python虚拟环境
切换的命令和virtualenv基本保持一致
pyenv activate env352
pyenv deactivate