如何在一个系统中维护多个版本的 Python?

  • pyenv
  • virtualenv

目录:

Python-版本管理

在一个系统中维护多个版本的 Python。

使用场景

  • A 项目使用 Python 2.7;B 项目使用 Python 3.5;
  • A、B 项目都使用 Python 2.7,但是使用的库不相同;
  • 每个项目可保持独立的 Python 版本及其依赖库,保证 Python 环境独立、干净;

相关工具

  • virtualenv ☆ ☆ ☆
    • A tool for creating isolated ‘virtual’ python environments.
  • pyenv ☆ ☆ ☆ ☆ ☆
    • Simple Python Version Management.
    • pyenv lets you easily switch between multiple versions of Python.
    • Common build problems
  • pyenv-virtualenv ☆ ☆ ☆ ☆ ☆
    • pyenv-virtualenv is a pyenv plugin that provides features to manage virtualenvs and conda environments for Python on UNIX-like systems.
  • 国内开源镜像站点汇总
  • 搜狐镜像 内含各个 Python 版本的压缩包

个人建议

  • 每个独立的 Python 项目创建一个独立的 Python 环境;
  • 使用 pyenv + pyenv-virtualenv 管理 Python 环境;

pyenv 和 pyenv-virtualenv 区别

  • pyenv-virtualenv 是 pyenv 的插件;
  • pyenv 安装 Python 时,每个 Python 版本只能安装一份,和官方版本一一对应,如 2.7.14;
  • pyenv-virtualenv 可以基于官方版本虚拟出任意数量的版本,更加灵活,如基于 2.7.14 虚拟出 app-server-2.7.14webapp-2.7.14 等;

常用命令

  • pyenv install version 安装,version 为对应的 Python 版本号,如 2.7.9;
  • pyenv virtualenv 3.5.2 webapp-3.5.2 以 3.5.2 版本创建虚拟环境;
  • pyenv uninstall version 删除 version 版本的 Python;
  • pyenv commands 列出所有命令;
  • pyenv versions 查看 pyenv 当前可检测到的所有版本,处于激活状态的版本前以 * 标示;
  • pyenv local 2.7.9 设置局部版本
  • pyenv which python 查看当前 python 命令的路径;
  • pyenv which pip 查看当前 pip 命令的路径;

pyenv

pyenv 官方文档

Ubuntu 安装

  • Installation 官方安装文档
  • git clone https://github.com/pyenv/pyenv.git ~/.pyenv clone pyenv 代码到本地;
  • echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc 定义环境变量 PYENV_ROOT
  • echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrcPYENV_ROOT 添加到 $PATH 路径中
  • echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bashrcpyenv init 命令添加到 shell 中
  • exec "$SHELL" 重启 shell,使配置生效

上述 echo 的三步相当于直接修改 ~/.bashrc 文件末尾添加下面的内容,后面的 pyenv-virtualenv 也类似:

~/.bashrc
1
2
3
4
5
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
eval "$(pyenv init -)"
fi

注:其中 ~/.bashrc 文件根据系统进行替换,例如:

  • Zsh note: ~/.zshenv
  • Ubuntu and Fedora note: ~/.bashrc

Mac 安装

  • 方法1:
    • brew install pyenv
    • ~/.bashrc 中添加上述代码片段
  • 方法2:同 Ubuntu 安装

卸载

管理不同版本的 Python

注:使用 pyenv 安装命令之前还需要安装相关依赖库,详见 Common build problems,Ubuntu/Debian 需要执行下面的命令:

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

安装需要的 Python 版本,安装之后的 Python 在 ~/.pyenv/versions 目录下:

  • pyenv install version 安装,version 为对应的 Python 版本号,如 2.7.9
  • pyenv uninstall version 删除 version 版本的 Python

注:阿里云通过上面命令安装的时候,一直无法从官网下载到 Python 安装包,最后谷歌找到下面的办法,还算好使:

  • cd ~/.pyenv/cache 进入 pyenv 缓存目录,没有 cache 目录时创建一个
  • wget http://mirrors.sohu.com/python/3.6.2/Python-3.6.2.tar.xz 手动从 搜狐镜像 下载一个 Python 安装包
  • pyenv install 3.6.2 使用 pyenv 安装,因为缓存中已经有了安装包,因此无需再去官网下载

不同级别的版本控制

pyenv 版本控制分下面三个级别,优先级依此增大:

  • global 配置全局 Python 版本,配置内容在 ~/.pyenv/version 文件中
    • pyenv global 2.7.9 设置全局版本,取消只能通过删除上述配置文件完成
  • local 设置局部 Python 版本,配置内容在当前目录的 .python-version 文件中
    • pyenv local 2.7.9 设置局部版本
    • pyenv local --unset 取消局部版本设置
  • shell 设置当前 shell 中的 Python 版本,参数存储在当前 shell 的 PYENV_VERSION 环境变量中
    • pyenv shell 2.7.9
    • pyenv shell --unset

常用命令

  • pyenv commands 列出所有命令;
  • pyenv versions 查看 pyenv 当前可检测到的所有版本,处于激活状态的版本前以 * 标示;
  • pyenv version 查看当前处于激活状态的版本,括号中内容表示这个版本是由哪条途径激活的;
  • pyenv rehash 为所有已安装的可执行文件(如:~/.pyenv/versions/*/bin/*)创建 shims,每当增删了 Python 版本或带有可执行文件的包(如 pip)以后,都应该执行一次本命令;
  • pyenv which python 查看当前 python 命令的路径
  • pyenv which pip 查看当前 pip 命令的路径

pyenv-virtualenv

pyenv-virtualenv 官方文档

Ubuntu 安装

  • Installation 官方安装文档
  • git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv clone 仓库到 pyenv 的插件目录;
  • echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc 添加 pyenv virtualenv-init 到 shell,自动激活插件;
  • exec "$SHELL" 重启 shell,使配置生效;

Mac 安装

  • 方法1:
    • brew install pyenv-virtualenv
    • echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
  • 方法2:同 Ubuntu 安装

创建虚拟 Python 版本

pyenv virtualenv [version] <virtualenv-name>

  • [version] 源版本,可选
  • <virtualenv-name> 虚拟环境名称

示例:

  • pyenv virtualenv 3.5.2 webapp-3.5.2 以 3.5.2 版本创建虚拟环境
  • pyenv virtualenv webapp-2.7.9 只有一个参数的时候,默认从当前 Python 版本创建虚拟环境

创建好的虚拟环境也会存在于 ~/.pyenv/versions 目录下,如 webapp-3.5.2,但这里只是一个软连接,文件实际存储在源版本根目录下的 envs 目录,如下所示:
webapp-3.5.2 -> /home/h39/.pyenv/versions/3.5.2/envs/webapp-3.5.2

常用命令

  • pyenv virtualenvs 列出所有的虚拟环境
  • pyenv uninstall webapp-2.7.9 删除虚拟环境
  • 设置 Python 版本同 pyenv 部分
  • 正确设置 virtualenvs 的情况下,进入或者退出包含 .python-version 的目录时会自动激活/关闭虚拟环境
  • 手动激活/关闭虚拟环境
    • pyenv activate webapp-2.7.9
    • pyenv deactivate

pip

pip 是一个 Python 包管理工具,主要是用于安装 PyPI 上的软件包。

示例

  • pip install -U pip or pip install --upgrade pip 更新 pip
  • pip install package_name 安装 package_name 包
  • pip --default-timeout=100 install package_name 设置超时时间,避免在网络很差的情况下每次安装都报超时错误
  • pip install package_name.whl 安装本地的 package_name.whl 文件
  • pip install --upgrade package_name 升级软件包
  • pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs pip install -U 升级安装的所有软件包
  • pip uninstall package_name 卸载 package_name 包
  • pip show --files package_name 查看安装的具体文件
  • pip list --outdated 查看过期的软件包(可升级的包)

批量管理

  • pip freeze > requirements.txt 导出当前环境依赖的软件包
  • pip install -r requirements.txt 在当前环境重建 requirements.txt 中的软件包

macOS pip 安装软件包失败

原因:macOS 引入了 SIP 管理机制,所以旧版本的 pip 创建的文件目录操作被拒绝,包括使用root也是如此。

解决办法:添加 --user 选项安装到用户包目录

  • pip install --user package_name

References