记录一下使用过程,留备以后使用。

pyenv 是 Python 版本管理工具。 pyenv 可以改变全局的 Python 版本,在系统中安装多个版本的 Python, 设置目录级别的 Python 版本,还能创建和管理 virtual python environments 。所有的设置都是用户级别的操作,不需要 sudo 命令。

pyenv 的一个典型使用场景就是,比如一个老项目需要使用 Python 2.x ,而另一个新项目需要 Python 3.x 。而 virtualenv 主要是用来管理相同版本 Python 不同项目的包的依赖不同的问题,就无法解决这个问题,这个时候就需要 pyenv。

pyenv 通过修改系统环境变量来实现不同 Python 版本的切换。而 virtualenv 通过将 Python 包安装到一个目录来作为 Python 包虚拟环境,通过切换目录来实现不同包环境间的切换。

pyenv 实现的精髓之处在于,它并没有使用将不同的 $PATH 植入不同的 shell 这种高耦合的工作方式,而是简单地在 $PATH 的最前面插入了一个垫片路径(shims):~/.pyenv/shims:/usr/local/bin:/usr/bin:/bin。所有对 Python 可执行文件的查找都会首先被这个 shims 路径截获,从而使后方的系统路径失效。

安装之前

不同系统请参考 Common build problems,安装必须的工具。

pyenv 安装

根据官网的 安装说明 或者 自动安装 。如果使用 Mac 直接使用 Homebrew。安装成功后记得在 .bashrc 或者 .bash_profile 中添加三行来开启自动补全。

export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

根据自己的环境配置。

自动安装

保证系统有 git ,否则需要新安装 git。

pyenv 提供了自动安装的工具,执行命令安装即可:1

或者:

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

这里需要特别提醒一句,不要在任何网站上复制粘贴命令到你的终端,除非你明确的知道你在做什么,如果你要检视这里的脚本可以先将脚本下载到本地,然后检查源码后执行安装,或者你可以使用后文提到的源码安装。

执行安装后提供了如下工具:

  • pyenv: pyenv 工具自身
  • pyenv-virtualenv: pyenv 的插件可以用来管理 vierual environments
  • pyenv-update: 用来更新 pyenv 的插件
  • pyenv-doctor: 验证 pyenv 和依赖是否安装的插件
  • pyenv-which-ext: 用来寻找相同命令的插件

pyenv 会从源代码编译 Python,所以需要安装必须的编译工具,安装 build 工具:

Debian/Ubuntu/Linux Mint:

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 libffi-dev liblzma-dev python-openssl

Fedora/CentOS/RHEL:

sudo yum install zlib-devel bzip2 bzip2-devel readline-devel sqlite \
sqlite-devel openssl-devel xz xz-devel libffi-devel

MacOS:

brew install openssl readline sqlite3 xz zlib

手动安装

如果想要更加详细的了解安装过程,可以使用手动安装。直接 clone pyenv 项目到 HOME 根目录。2 建议路径为:$HOME/.pyenv

然后将如下内容复制到 bashrc:

export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

reload bashrc:

source ~/.bashrc

这里的 shell 配置文件(~/.bash_profile)需要按照不同 Linux 作修改,如果使用 Zsh 则需要相应的配置 ~/.zshrc

在使用 pyenv 之后使用 pip 安装的第三方模块会自动安装到当前使用 python 版本下,不会和系统模块产生冲突。使用 pip 安装模块之后,如果没有生效,记得使用 pyenv rehash 来更新 shims 路径。

pyenv 常用命令

使用 pyenv commands 显示所有可用命令

python 安装与卸载

就如上文所说,pyenv 从源码安装 Python, 每一个安装的版本都会在 pyenv 根目录的 versions 目录下。

pyenv install 2.7.3   # 安装 python

安装后可以检视:

ls ~/.pyenv/versions/

从本机卸载对应版本的 Python 也特别简单:

pyenv uninstall 2.7.3 # 卸载 python

或者直接删除掉 ~/.pyenv/versions/2.7.3 对应的目录也可以。

rm -rf ~/.pyenv/versions/2.7.3

查看本机安装 Python 版本

使用如下命令查看本机安装版本

pyenv versions

星号表示当前正在使用的 Python 版本。使用 python -V 确认版本。

查看可安装 Python 版本

使用如下命令查看可安装版本

pyenv install -l

Python 切换

用这些命令可以切换全局或者项目中的 Python 版本:

pyenv global 2.7.3  # 设置全局的 Python 版本,通过将版本号写入 ~/.pyenv/version 文件的方式。
pyenv local 2.7.3 # 设置 Python 本地版本,通过将版本号写入当前目录下的 .python-version 文件的方式。通过这种方式设置的 Python 版本优先级较 global 高。

需同在寻找 python 的时候优先级

shell > local > global

pyenv 会从当前目录开始向上逐级查找 .python-version 文件,直到根目录为止。若找不到,就用 global 版本。

pyenv shell 2.7.3 # 设置面向 shell 的 Python 版本,通过设置当前 shell 的 PYENV_VERSION 环境变量的方式。这个版本的优先级比 local 和 global 都要高。`--unset` 参数可以用于取消当前 shell 设定的版本。

pyenv shell --unset

pyenv rehash  # 创建垫片路径(为所有已安装的可执行文件创建 shims,如:~/.pyenv/versions/*/bin/*,因此,每当你增删了 Python 版本或带有可执行文件的包(如 pip)以后,都应该执行一次本命令)

pyenv-virtualenv

pyenv 插件:pyenv-virtualenv

使用自动安装 pyenv 后,它会自动安装部分插件,通过 pyenv-virtualenv 插件可以很好的和 virtualenv 结合:

cd ~/.pyenv/plugins
ll
total 24K
drwxr-xr-x 4 einverne einverne 4.0K Apr 22 10:55 pyenv-doctor
drwxr-xr-x 5 einverne einverne 4.0K Apr 22 10:55 pyenv-installer
drwxr-xr-x 4 einverne einverne 4.0K Apr 22 10:55 pyenv-update
drwxr-xr-x 7 einverne einverne 4.0K Apr 22 10:55 pyenv-virtualenv
drwxr-xr-x 4 einverne einverne 4.0K Apr 22 10:55 pyenv-which-ext
drwxr-xr-x 5 einverne einverne 4.0K Apr 22 10:54 python-build

创建虚拟环境

pyenv virtualenv 2.7.15 env-name

若不指定 python 版本,会默认使用当前环境 python 版本。如果指定 Python 版本,则一定要是已经安装过的版本,否则会出错。环境的真实目录位于 ~/.pyenv/versions

列出当前虚拟环境

pyenv virtualenvs
pyenv activate env-name  # 激活虚拟环境
pyenv deactivate #退出虚拟环境,回到系统环境

删除虚拟环境

pyenv uninstall env-name
rm -rf ~/.pyenv/versions/env-name  # 或者删除其真实目录

使用 pyenv 来管理 python,使用 pyenv-virtualenv 插件来管理多版本 python 包。此时,还需注意,当我们将项目运行的 env 环境部署到生产环境时,由于我们的 python 包是依赖 python 的,需要注意生产环境的 python 版本问题。

所有命令

$ pyenv commands
activate
commands
completions
deactivate
doctor
exec
global
help
hooks
init
install
installer
local
offline-installer
prefix
rehash
root
shell
shims
uninstall
update                 # 更新 pyenv 及插件
version
--version
version-file
version-file-read
version-file-write
version-name
version-origin
versions
virtualenv
virtualenv-delete
virtualenv-init
virtualenv-prefix
virtualenvs
whence
which

PyCharm

PyCharm 中可以非常方便的切换 Python 环境非常方便。但是因为个人原因 Java 和 Python 同时用的概率比较高,所以一直使用 Intellij IDEA 安装了 Python 插件。PyCharm 是为 Python 单独开发,所以如果不需要在语言之间切换用 PyCharm 还是比较方便的。

Tips

更换 pip 源

因为国内网络环境,如果在局域网内下载 pip 慢,可以尝试使用 aliyun 提供的镜像,创建 vim ~/.pip/pip.conf ,然后填入:

[global]
index-url = http://mirrors.aliyun.com/pypi/simple/

[install]
trusted-host=mirrors.aliyun.com

延伸

不仅 Python 有 pyenv 可以用来管理 Python 的不同版本,Java,Ruby 也都有相对应的工具。

比如说 Java 的 jenv, Ruby 有 rbenv,它们命令的用法也都和 pyenv 相差不多,基本上用了 pyenv,其他几个命令的使用也都水到渠成了。

参考

  1. https://github.com/pyenv/pyenv-installer

    curl https://pyenv.run bash

  2. https://github.com/pyenv/pyenv#basic-github-checkout

    cd ~ git clone git://github.com/yyuu/pyenv.git .pyenv