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