python:pyenv

2,376 阅读6分钟

图片.png

参考网址

zhuanlan.zhihu.com/p/36402791 www.jianshu.com/p/20cd2fc91… www.jianshu.com/p/1842a3632…

1/问题情景

<1>python解释器版本混乱,有很多种版本, 23差别巨大, 而且细分版本也不尽相同, 难以选择和管理.
<2>不同linux发行版自带python的版本不同, 如ubuntu16自带2.73.5版本, 
    其中系统许多组件依赖于自带解释器, 一旦删除或者更改都可能会造成系统出问题.
<3的python版本的软件包(扩展包)管理也是问题, 如pip和ipython等必备包组件, 
   而且在项目开发中如何保证不同的包环境互不干扰也是一个问题.

那么有没有一个终极的解决办法能在管理不同解释器版本的同时控制不同的包环境呢? 有的, 就是pyenv.

2/pyenv是什么? 能干什么?

pyenv是python版本管理器

python版本有:
   2.x。x
   3.x。x
   Anaconda2
   Anaconda3

我们都知道,服务器上可以同时安装多个版本的python解释器,比如python2.7,python3.5,python3.7等。
我们在开发不同的python项目的时候,可能会因为实际的需要,不同的项目会用不同版本的python解释器来执行。
那么我们怎么对系统中不同版本的python来进行管理呢?
pyenv是python版本的管理器。可以在系统里同时保留多个python版本。
为不同的python版本取不同的名字。不同的项目用不同python版本作为解释器。

pyenv是一个python环境管理工具, 它可以轻松切换全局解释器版本,
同时结合vitualenv插件可以方便的管理对应的包源.

我们知道, 在terminal中输入一个命令比如‘ls’时,
shell会从当前环境的PATH中的各个目录里看是不是有ls这个可执行文件, 
如果找到就执行, 否则就会报‘command no found’ 的错误.
同理, 只要控制PATH变量就能够做到python版本的切换, pyenv通过在PATH头部插入shims路径来实现对python版本的控制.

image.png

3/pyenv和pipenv,virtualenv的关系

pipenv是一个python虚拟环境管理工具, 结合了pip和virtualenv的功能,侧重点还是在包管理上。
使用思路是先创建一个指定python版本的环境, 然后在此环境上安装相应的包。
好评不错, 看到很多大牛都在推荐.

virtualenv是一个比较传统成熟的虚拟环境管理工具了, 用的人也比较多。
思路也是创建虚拟环境, 然后安装相应的包, 要进入环境就source一下activate脚本激活一下。
尽管成熟, 但是我个人不太喜欢用, 在部署项目的时候老是容易出现一些环境问题.

pyenv相对来说知名度就差很多了, 不过也很稳定, 这三个环境管理工具我都用过, 我个人更喜欢pyenv, 
理由如下:
<1> 相对于其他两个工具, pyenv更侧重在python解释器版本管理上, 比包管理更大一个层级。
    使用pyenv我可以方便的下载指定版本的python解释器,可以随时自由的在shell环境中本地、全局切换python解释器
    
<2>开发的时候不需要限定某个版本的虚拟环境, 只需要在部署的时候用pyenv指定某个版本就好了
<3>pyenv切换python解释器版本的时候, pip和ipython以及对应的扩展包都是一起切换的, 
   所以如果你要同时运行ipython2.x和ipython3.x多个解释器验证一些代码时就很方便
<4>pyenv也可以创建好指定的虚拟环境, 但不需要指定具体目录, 自由度更高, 使用也简单

4/安装pyenv

<1> 如果你是linux系统
    以git clone的方式安装pyenv工具,安装在~/.pyenv
    $ git clone https://github.com/pyenv/pyenv.git ~/.pyenv

<2>如果你是MacOS系统
      可以直接用homebrew安装
    $ brew update
    $ brew install pyenv 

<3>添加shell配置文件中追加如下: (如~/.zshrc文件,或者~/.bash_profile文件)
    export PYENV_ROOR="$HOME/.pyenv"
    export PATH=$PATH:$PYENV_ROOT/shims
    eval "$(pyenv init -)"
    eval "$(pyenv virtualenv-init -)"

<3>source一下配置文件,
    source .bash_profile

<4>输入pyenv --version测试一下pyenv是否安装成功
    如果显示版本号,则代表安装成功

4/通过pyenv install xxx安装的python解释器都在哪里

都在~/.pyenv/versions这个目录下
前提是:你把pyenv这个工具安装在了哪里。然后进入到.pyenv,然后在进入到目录下的versions目录就好了

5/简单的使用

# 查看当前版本
pyenv --version

# 查看pyenv目前已经管理了哪些python版本(即已经pyenv工具安装的python版本)
pyenv versions

# 查看所有可以安装的python版本,从中找到自己需要安装的版本
pyenv install --list  或者pyenv install -l 
如下所示:
例如 
 pyenv install anaconda2-4.2.0

# 安装指定版本的python
pyenv install 3.6.5  # 安装3.6.5版本的python解释器

# 安装新版本后rehash一下
pyenv rehash

# 删除指定版本
pyenv uninstall 3.5.2

# 指定全局版本,及把某个python版本作为默认的解释器
# 各个项目都是用这个默认的版本的python作为解释器来执行
pyenv global 3.6.5

# 指定多个全局版本, 3版本优先
pyenv global 3.6.5 2.7.14

# 实际上当你切换版本后, 相应的pip和包仓库都是会自动切换过去的

pyenv命令的简单介绍

pyenv commands:查看所有pyenv命令
pyenv exec:使用特定Python版本执行某条命令
pyenv global:设置或查看全局Python版本
pyenv hooks:列出给出的pyenv命令的钩子脚本
pyenv init:配置shell环境
pyenv install:安装某个版本的Python
pyenv local:为某个应用设置特定的Python版本
pyenv prefix:显示对应Python版本的路径前缀
pyenv rehash:再哈希pyenv shims(不清楚有什么用,欢迎评论补充)
pyenv root:显示pyenv根目录
pyenv shell:为某个shell设置特定的Python版本(与pyenv local类似)
pyenv shims:列出当前存在的shims(pyenv的工作原理就是在一个叫shims的目录下创建Python解释器的“假版本”,寻找Python应用时先从该目录查找)
pyenv uninstall  xxx:卸载某个版本Python
pyenv --version:显示pyenv版本
pyenv version:显示当前Python版本,等价于pyenv version-name+pyenv version-file
pyenv version-file/version-name/version-origin:当前Python版本对应的文件/名字/位置
pyenv whence:列出已安装的一个范围内的Python版本,比如列出本地安装的Python2到Python3的版本,可以使用pyenv whence 2to3
pyenv which:列出可执行文件的绝对路径,比如pyenv which python可以列出python命令的绝对路径

6/更新pyenv本身,或者卸载pyenv本身

<1>更新pyenv
   由于我们是 git 克隆的,所以更新非常简单
   cd ~/.pyenv` 或者 `cd $(pyenv root)`
   git pull

<2>卸载pyenv本身
  由于 pyenv 把一切都放在 ~/.pyenv 下了,所以卸载很方便,两个步骤就行了
  首先你需要删除环境变量
  然后你需要执行:
  rm -rf ~/.pyenv` 或者 `rm -rf $(pyenv root)

6/包管理插件pyenv-virtualenv

如果是linux服务器:
$ git clone https://github.com/pyenv/pyenv-virtualenv.git $.pyenv/plugins/pyenv-virtualenv

克隆完成后添加如下到shell配置文件(mac的话是.zshrc
$ echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bash_profile


实际上mac用户直接brew安装就可以了...
    $ brew install pyenv-virtualenv
    $ eval "$(pyenv init -)"
    $ eval "$(pyenv virtualenv-init -)"


使用:
  # 创建一个3.6.5版本的虚拟环境, 命名为v365env
  # 这里是创建了一个虚拟环境,指定了python解释器的版本是3.6.5,但是前提是已经安装了3.6.5版本的python,如果没有安装,则需要pyenv install 3.6.5
  # 这个环境的真实目录位于~/.pyenv/versions/
  $ pyenv virtualenv 3.6.5 v365env
  
  # 激活环境,并进入环境
  $ pyenv activate v365env
  
  # 关闭虚拟环境
  $ pyenv deactivate v365env
  
  # 删除虚拟环境
  pyenv virtualenv-delete v365env
  
  
当切换python解释器的时候对应的pip和包库也会一并切换过去, 
而且可以为指定版本的解释器创建项目所需的虚拟环境, 切换的时候也异常简单, 个人常用的做法是为每个项目创建不同的虚拟环境, 当进入该环境的时候就可以随便浪而不用担心影响到其它项目, 搭配Pycharm使用效果更佳.

pyenv和conda的相同点与不同点

 conda是环境管理器,也是库包管理器(这一点和pip一样),这是二者类似的地方。
 conda自带于anaconda,所以不需要额外安装,在anacnoda的bin目录下就可以直接执行conda命令。

总结

pyenv可以在系统中安装不同版本的python解释器,
比如python2.7,python3.5,anaconda2,anaconda3,miniconda2等不同版本的解释器。

然后配合pyenv-virtualenv插件,可以创建虚拟环境,该虚拟环境可以指定一定版本的python解释器。
环境可以随意创建,激活,切换,删除。
    

pyenv-virtualenv的使用

有了pyenv virtualenv以后,我们可以为同一个Python解释器,创建多个不同的工作环境。
例如,我们 新建两个工作环境:
[root@python ~]# pyenv virtualenv 3.8.1 first_project 
[root@python ~]# pyenv virtualenv 3.8.1 second_projec

可以使用virtualenvs子命令查看工作环境:
[root@python ~]# pyenv virtualenvs
  3.8.1/envs/first_project (created from /root/.pyenv/versions/3.8.1)
  3.8.1/envs/second_projec (created from /root/.pyenv/versions/3.8.1)
  first_project (created from /root/.pyenv/versions/3.8.1)
  second_projec (created from /root/.pyenv/versions/3.8.1)
  
创建完工作环境以后,可以通过activate和deactivate子命令进入或退出一个工作环境。
进入工作环境 以后,左边的提示符会显示你当前所在的工作环境,以免因为环境太多导致操作错误。
(first_project) [root@python ~]# pip install flask==1.1.1 
Looking in indexes: https://pypi.doubanio.com/simple
Collecting flask==1.1.1
  Downloading https://pypi.doubanio.com/packages/9b/93/628509b8d5dc749656a9641f4caf13540e2cdec85276964ff8f43bbb1d3b/Flask-1.1.1-py2.py3-none-any.whl (94kB)
     |███▌                            | 10kB 28.0MB/s eta 0:00:
     |███████                         | 20kB 1.8MB/s eta 0:00:0
     |██████████▍                     | 30kB 2.7MB/s eta 0:00:0
     |█████████████▉                  | 40kB 1.8MB/s eta 0:00:0
     |█████████████████▍              | 51kB 1.3MB/s eta 0:00:0
     |████████████████████▉           | 61kB 1.5MB/s eta 0:00:0
     |████████████████████████▎       | 71kB 1.4MB/s eta 0:00:0
     |███████████████████████████▊    | 81kB 1.3MB/s eta 0:00:0
     |███████████████████████████████▏| 92kB 1.4MB/s eta 0:00:0
     |████████████████████████████████| 102kB 1.6MB/s 
Collecting itsdangerous>=0.24 (from flask==1.1.1)
(first_project) [root@python ~]# pyenv deactivate
##退出first_project环境
[root@python ~]# 


接下来,我们看一下在不同的工作环境安装不同的Flask版本:
[root@python ~]# pyenv activate first_project 
##切换工作环境
(first_project) [root@python ~]# pip install flask==1.1.1 
##安装1.1.1的flask
(first_project) [root@python ~]# pyenv deactivate 
##退出目前工作环境
[root@python ~]#

[root@python ~]# pyenv activate second_projec
##切换工作环境
(second_project) [root@python ~]# pip install flask==0.10.1
##安装0.10.1的flask
(second_project) [root@python ~]# pyenv deactivate 
##退出目前工作环境
[root@python ~]#