简介
之前的文章(Python2还是python3 )中我们提到,建议现在大家都采用python3,因为python2在今年年底将不在维护。但在实际的开发和使用python过程中,我们避免不了还得用到python2,如何让python2和python3共存?之前网上很多教程很多是让配置一个默认的python,然后再配置一个python2,这样输入python调用的是python3,输入python2调用的python2。这样做也可以使用,但是还不够优雅,因为牵扯到很多环境变量的配置。
于是就有人参考ruby的版本管理工具rbenv,开发了可以管理python版本的工具:pyenv。 需要提前说明,pyenv只能用在mac/linux系统使用(本文主要也是基于mac来介绍的),windows系统需要用到另外的工具,文章的最后会做介绍。
pyenv的使用
原理
相信大家都对系统的环境变量PATH比较熟悉,mac通常用:分隔路径(windows是用;分隔)比如:/usr/local/bin:/usr/bin:/bin。当我们在命令行输入某一个命令,比如:python或者pip,系统会去我们配置的环境变量中从左向右依次查找对应的命令,因此排在前面的路径优先级会更高。
pyenv正是利用了这一特性,当用户使用python相关命令时,pyenv会拦截到这一过程,然后将自己管理的python版本的shim目录插入到PATH 中/usr/local/bin:/usr/bin:/bin最前面,这样,当系统去查找python等命令时,就会优先查找pyenv设置的目录,从而达到可以灵活切换python版本的目的。
想了解pyenv实现的同学,可以直接去github上查看其源码及更详细的介绍文档。
安装
pyenv提供了三种方式来安装,这里推荐使用pyenv-installer来安装,因为足够简单,同时还会安装一些比较实用的工具插件:
pyenv-doctor (用于检测pyenv的环境)
pyenv-installer
pyenv-update (用于更新)
pyenv-virtualenv (用于区分依赖库的不同版本,后面会介绍)
pyenv-which-ext
安装命令如下:
$ curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
# the following to ~/.zshrc:
export PATH="/Users/xuanke/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
命令执行完后,没有报错就是安装完成了,不过会提示你需要配置pyenv的环境变量(如上面所示)。其中pyenv init命令是将pyenv的shim目录添加到PATH中。我们可以验证下,修改完.zshrc之后,执行source ~/.zshrc让配置生效,然后我们打印环境变量PATH,如下:
从上图可以看出,pyenv的配置已经被插入到/usr/local/bin:/usr/bin:/bin的前面。
更新
使用pyenv update命令,可对pyenv直接进行升级。
卸载
这里要分两种场景:1)暂时不想用pyenv,但是不想删除。 2)彻底删除。
针对第一种情况,仅仅需要将pyenv init的配置从~/.zshrc中移除,这样就不会将pyenv的shim目录添加到PATH的前面。
针对第二种情况,可以通过删除pyenv实现,命令如下:
# 1. 删除pyenv的安装目录 $ rm -rf $(pyenv root) # 2. 删除在~/.zshrc中配置的pyenv环境变量
pyenv主要命令
我们可以执行pyenv -h查看pyenv的主要命令:
pyenv install
pyenv install用于安装对应的python包,同时加上--list参数,可以用来查看可以安装的包列表。
然后用pyenv install + 版本号,就可以安装对应版本的python。
需要注意,有时候需要安装python Framework,则需要使用下面的命令:
PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install 3.6.4
pyenv uninstall
用于卸载本地已经安装的python版本
将versions目录下面的对应版本的包删除掉。
pyenv versions
查看本地已经安装可用的python版本,其中前面标*的,是本地当前版本。
pyenv version
用于查看本地当前设置的python版本
python 版本切换
pyenv的版本主要有三个维度:shell、项目目录、全局(global),它们三者的优先级依次降低,即如果设置了shell,又设置了全局的,那么以shell配置的python版本为主。接下来我们看看这三种维度下怎么修改python版本。
如果想要修改全局的python版本,那么可以使用python global pythonVersion,该命令会同步在pyenv的根目录(默认是~/.pyenv/)下创建一个version的文件,文件内容是要切换的python版本号,如下所示:
如果你的某个项目需要特定的python版本,也是可以实现的。可以使用python local pythonVersion,该命令会同步在项目目录下,创建一个.python-version的文件,文件内容是切换的版本号,如下所示:
如果你只希望临时对shell的python版本做变更,可以使用python shell pythonVersion, 该命令会同步在当前的shell窗口创建一个PYENV_VERSION的环境变量,如下图所示。如果重启了shell窗口,或者新建一个shell窗口,则PYENV_VERSION不起作用,也就是其作用域仅仅在当前的shell。如果想取消shell级别的python环境,可以执行命令:unset PYENV_VERSION。
我们再来验证下三者的优先级,我们将全局的python版本设置为3.7.4,然后将shell的python版本设置为2.7.16,然后执行pyenv version,如下所示:
从上面的结果可以证明,shell的优先级是要高于全局的。
在windows上使用pyenv
pyenv并没有直接支持windows版本,但是通过pyenv-win项目来支持windows的使用,我们可以通过pip或者直接从github将pyenv-win的代码下载到本地用户目录,一般是:%USERPROFILE%/.pyenv。然后可以将%USERPROFILE%.pyenvpyenv-winin;%USERPROFILE%.pyenvpyenv-winshims 配置到环境变量PATH的最前面,然后重启命令行窗口,执行:pyenv --version 命令查看pyenv配置是否成功。
pyenv在windows上的使用和mac上类似,因为我没有在windows上对pyenv的命令逐条尝试,所以这里我贴一个github上面的命令使用说明:
一个项目需要多套环境
还有一种场景,假如我们有一个项目,但是这个项目却需要对应两个python环境,这两个环境对应的依赖包肯定是不一样的,这应该怎么办呢?貌似直接通过pyenv没办法实现。 其实上面已经提到过,pyenv提供了一个插件工具pyenv-virtualenv,这个工具可以帮我们实现环境的分离。它的使用方法如下:
$ pyenv virtualenv pythonVersion projectName
其中pythonVersion对应的是python的版本号,projectName对应的是项目的名称(可以带上python版本的标识),比如我们现在有个pythonDemo的项目,我们为他基于python2.x和python3.x创建两套依赖库环境:
从上面我们可以看出,虚拟环境被创建在了pyenv/versions/version/envs目录下。
创建完成后,我们可以通过pyenv virtualenvs查看已经创建的虚拟环境。
之后我们可以通过pyenv activate projectName(比如:pythonDemo_2.7.16) 来切换项目对应的虚拟环境。通过pyenv deactivate来退出虚拟环境。
总结
上面是pyenv的常用的介绍,相信已经可以帮助大家来比较方便的管理python版本,希望大家在之后的工作中能立即使用起来,这样才能将pyenv消化掉,告别依靠各种配置环境变量来管理python版本的方式。