好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Python多版本管理器-pyenv 介绍及部署记录

?

一. pyenv简单介绍

在日常运维中, 经常遇到这样的情况: 系统自带的Python是2.x,而业务部署需要Python 3.x 环境, 此时需要在系统中安装多个Python版本,但又不能影响系统自带的Python 版本,即需要实现Python的多版本环境共存, pyenv就是这样一个Python版本管理器, 可以同时管理多个python版本共存! 简单的说,pyenv 可以根据需求使用户在系统里安装和管理多个Python 版本: - 配置当前用户的python的版本; - 配置当前shell的python版本; - 配置某个项目(目录及子目录)的python版本; - 配置多个虚拟环境.

由于python的各种优点,当前学习及使用python的人越来越多, 学习python有一个不容忽视的问题就是python的版本问题! 到现在为止,python的版本有很多,但是问题在于python2与python3的区别。python3的对一些模块进行了改变,导致了python2写的代码有的不被python3兼容,从而导致程序运行报错。因此,在学习和工作中使用python的时候,最好是安装一个pyenv管理器, 多安装几个python版本进行管理, 然后再针对不同项目安装各自项目的python虚拟环境, 相互隔离, 这样便于使用和管理。

二. pyenv工作原理

pyenv是利用系统环境变量PATH的优先级,劫持python的命令到pyenv上,根据用户所在的环境或目录,使用不同版本的python。

how?it?works:
At?a?high?level,?pyenv?intercepts?Python?commands?using?shim?executables?injected?into?your?PATH,?determines?which?Python?version?
has?been?specified?by?your?application,?and?passes?your?commands?along?to?the?correct?Python?installation.

它是如何工作的:
在较高级别上,pyenv使用注入到PATH中的shim可执行文件拦截Python命令,确定应用程序指定了哪个Python版本,并将命令传递到正确的Python安装。

对于系统环境变量 PATH ,里面包含了一串由冒号分隔的路径,例如 /usr/local/bin:/usr/bin:/bin。每当在系统中执行一个命令时,例如 python 或 pip,操作系统就会在 PATH 的所有路径中从左至右依次寻找对应的命令。因为是依次寻找,因此排在左边的路径具有更高的优先级。在PATH 最前面插入一个 $(pyenv root)/shims 目录,$(pyenv root)/shims目录里包含名称为python以及pip等可执行脚本文件;当用户执行python或pip命令时,根据查找优先级,系统会优先执行shims目录中的同名脚本。pyenv 正是通过这些脚本,来灵活地切换至我们所需的Python版本。

三. pyenv安装和使用说明

1) pyenv安装

[root@localhost?~]#?cat?/etc/redhat-release
CentOS?release?6.9?(Final)
??
系统默认是Python?2.6?版本
[root@localhost?~]#?python?-V?????????????
Python?2.6.6
??
1)?安装依赖环境
[root@localhost?~]#?yum?-y?install?gcc?zlib-devel?bzip2-devel?openssl-devel?ncurses-devel?sqlite-devel?readline-devel?tk-devel?gdbm-devel?db4-devel?libpcap-devel?xz-devel?git
??
2)?安装pyenv包
pyenv可以通过多种方式安装,可以参考项目在github上的Installtion,?地址为:?https://github测试数据/pyenv/pyenv-installer
??
推荐采用The?automatic?installer的方式安装,可以一键安装pyenv的所有插件。
[root@localhost?~]#?curl?-L?https://github测试数据/pyenv/pyenv-installer/raw/master/bin/pyenv-installer?|?bash

pyenv套件下插件:
-?pyenv-doctor
-?pyenv-installer
-?pyenv-update
-?pyenv- Virtual env
-?pyenv-which-ext

==================================================================================
温馨提示:
以上https://github测试数据/pyenv/pyenv-installer/raw/master/bin/pyenv-installer的访问内容
,?可以将内容粘出来放在服务器的一个shell脚本文件中,?然后执行该脚本用以安装pyenv
?????
该脚本下载地址:??https://pan.baidu测试数据/s/1wW9ylrmc4Q9wxu_i3-1wYA
提取密码:?rhtj
?????
执行脚本进行安装(执行前授予755权限)
#?chmod?755?pyenv-installer
#?/bin/bash?pyenv-installer
=================================================================================
??
分析一下上面的pyenv-installer脚本,可以发现在centos上,其实它做了以下事情:
git?clone?--depth?1"git://github测试数据/pyenv/pyenv.git"????????????"${HOME}/.pyenv"
git?clone?--depth?1"git://github测试数据/pyenv/pyenv-doctor.git"?????"${HOME}/.pyenv/plugins/pyenv-doctor"
git?clone?--depth?1"git://github测试数据/pyenv/pyenv-installer.git"??"${HOME}/.pyenv/plugins/pyenv-installer"
git?clone?--depth?1"git://github测试数据/pyenv/pyenv-update.git"?????"${HOME}/.pyenv/plugins/pyenv-update"
git?clone?--depth?1"git://github测试数据/pyenv/pyenv- Virtual env.git""${HOME}/.pyenv/plugins/pyenv- Virtual env"
git?clone?--depth?1"git://github测试数据/pyenv/pyenv-which-ext.git"??"${HOME}/.pyenv/plugins/pyenv-which-ext"
??
上面安装完成后,还需要执行下面的命令,将pyenv安装到系统环境变量中。
[root@localhost?~]#?ll?-d?/root/.pyenv
drwxr-xr-x?11?root?root?4096?Dec?17?10:48?/root/.pyenv
??
在~/.bash_profile文件底部添加下面三行内容, 让系统可以找到?pyenv?安装的?Python
[root@localhost?~]#?vim?~/.bash_profile???????
export?PATH="/root/.pyenv/bin:$PATH"
eval?"$(pyenv?init?-)"
eval?"$(pyenv? Virtual env-init?-)"
??
使上面配置生效
[root@localhost?~]#?source?~/.bash_profile
??
查看pyenv安装情况
[root@localhost?~]#?pyenv?--version????????????//或者"pyenv?-v"
pyenv?1.2.8
??
更新pyenv
[root@localhost?~]#?pyenv?update
??
3)?卸载pyenv
先删除pyenv的安装目录,??这里即是/root/.pyenv
[root@localhost?~]#?rm?-fr?/root/.pyenv
??
接着删除~/.bash_profile里面配置的系统环境变量
[root@localhost?~]#?vim?~/.bash_profile     //删除下面三行
export?PATH="/root/.pyenv/bin:$PATH"
eval?"$(pyenv?init?-)"
eval?"$(pyenv? Virtual env-init?-)"
??
[root@localhost?~]#?source?~/.bash_profile
??
这样pyenv就被卸载了, 卸载pyenv后, 当前终端shell里会出现"-bash:?pyenv:?command?not?found"
的提示信息, 不过不影响使用. 再打开其他的终端窗口, 就不会出现该提示信息.

2) pyenv使用

当前系统默认的Python版本
[root@localhost?~]#?python?-V
Python?2.6.6
??
pyenv的命令,可以通过pyenv?help查看
[root@localhost?~]#?pyenv?help
Usage:?pyenv?<command>?[<args>]
??
Some?useful?pyenv?commands?are:
???commands????List?all?available?pyenv?commands
???local???????Set?or?show?the?local?application-specific?Python?version
???global??????Set?or?show?the?global?Python?version
???shell???????Set?or?show?the?shell-specific?Python?version
???install?????Install?a?Python?version?using?python-build
???uninstall???Uninstall?a?specific?Python?version
???rehash??????Rehash?pyenv?shims?(run?this?after?installing?executables)
???version?????Show?the?current?Python?version?and?its?origin
???versions????List?all?Python?versions?available?to?pyenv
???which???????Display?the?full?path?to?an?executable
???whence??????List?all?Python?versions?that?contain?the?given?executable
??
See?`pyenv?help?<command>'?for?information?on?a?specific?command.
For?full?documentation,?see:?https://github测试数据/pyenv/pyenv#readme
??
使用?pyenv?install?--list?查看可以安装的python版本
[root@localhost?~]#?pyenv?install?--list
Available?versions:
??2.1.3
??2.2.3
??.........
??2.7.4
??2.7.5
??.........
??3.0.1
??3.1
??.........
??3.6.1
??3.6.2
??.........
??3.7.1
??3.8-dev
??
查看当前pyenv可检测到的所有版本,处于激活状态的版本前以?*?标示.
[root@localhost?~]#?pyenv?versions
*?system?(set?by?/root/.pyenv/version)
??
使用pyenv?install??<version>?安装python,可以使用-v参数,查看安装过程。
如下,?分别安装三个版本的python
[root@localhost?~]#?pyenv?install?-v?2.7.5
[root@localhost?~]#?pyenv?install?-v?3.1
[root@localhost?~]#?pyenv?install?-v?3.6.1
??
查看当前pyenv可检测到的python版本?(即pyenv当前安装了哪些python版本)
[root@localhost?~]#?pyenv?versions
*?system?(set?by?/root/.pyenv/version)
??2.7.5
??3.1
??3.6.1
??
查看当前pyenv使用的python版本???(注意是version,?而不是上面的versions)
[root@localhost?~]#?pyenv?version
system?(set?by?/root/.pyenv/version)
??
配置及管理python版本
pyenv管理python版本的三个基础命令(即使用下面三个命令的途径进行python版本的切换和激活状态):
-?pyenv?global?<version>?????//?配置当前用户的系统使用的python版本.?可以使用这个命令进行python版本的切换!
-?pyenv?shelll?<version>??????//?配置当前shell的python版本,退出shell则失效
-?pyenv?local?<version>??????//?配置所在项目(目录)的python版本
??
特别注意:
在使用上面pyenv三个基础命令进行python版本切换后:
如果想要切回到系统默认的python版本,?也就是这里默认的python2.6.6,?则需要下面命令进行切回操作!!!!!!
[root@localhost?p_b]#?pyenv?local?system
[root@localhost?p_b]#?python?-V???????
Python?2.6.6
??
下面分别介绍下pyenv这三个基础命令切换python版本的操作
a)?使用pyenv?global?<version>配置当前用户的系统使用的python版本
[root@localhost?~]#?pyenv?versions
*?system?(set?by?/root/.pyenv/version)
??2.7.5
??3.1
??3.6.1
??
[root@localhost?~]#?python?-V
Python?2.6.6
??
使用下面命令进行python版本的切换
[root@localhost?~]#?pyenv?global?3.6.1
??
[root@localhost?~]#?pyenv?versions
??system
??2.7.5
??3.1
*?3.6.1?(set?by?/root/.pyenv/version)
??
[root@localhost?~]#?python?-V
Python?2.6.6
??
需要执行下面命令进行数据库更新后,?pyenv切换的python版本才会生效!
[root@localhost?~]#?pyenv?rehash
??
[root@localhost?~]#?python?-V???????
Python?3.6.1
??
[root@localhost?~]#?which?python
/root/.pyenv/shims/python

=================================================================================
特别注意:如果使用"pyenv?global?xxx"?以及?"pyenv?rehash"?后仍然无法成功切换版本!
这种情况一般是因为用pyenv指定了local版本!!
解决办法:取消设置local版本,即执行"pyenv?local?--unset"即可!
=================================================================================
??
b)?使用pyenv?shelll?<version>配置当前shell的python版本,退出shell则失效
[root@localhost?~]#?python?-V
Python?3.6.1
[root@localhost?~]#?pyenv?versions
??system
??2.7.5
??3.1
*?3.6.1?(set?by?/root/.pyenv/version)
[root@localhost?~]#?pyenv?shell?2.7.5
[root@localhost?~]#?python?-V??????
Python?2.7.5
??
如上设置后,?只在当前shell终端窗口有效,?退出重新登录?或?再打开另外一个窗口就不生效了?(即pytho版本还是之前的)
即使执行"pyenv?rehash"?进行更新操作,?在别的shell窗口也是不生效的!
??
当前shell下,取消配置的使用python?shell?--unset;若退出此shell,配置也会失效。
[root@localhost?~]#?pyenv?shell?--unset
[root@localhost?~]#?python?-V????????
Python?3.6.1
??
c)?使用pyenv?local?<version>配置所在项目(目录)的python版本
新建一个文件夹~/project,在此文件夹下使用python?local?<version>
[root@localhost?~]#?python?-V??
Python?3.6.1
[root@localhost?~]#?mkdir?project
[root@localhost?~]#?cd?project/
[root@localhost?project]#?pyenv?local?3.1
[root@localhost?project]#?pyenv?versions
??system
??2.7.5
*?3.1?(set?by?/root/project/.python-version)
??3.6.1
??
在当前项目目录下查看python版本
[root@localhost?project]#?python?-V
Python?3.1
??
新建目录~/project/p_a,切换到~/project/p_a,并查看版本
[root@localhost?project]#?mkdir?p_a&&?cd?p_a
[root@localhost?p_a]#?python?-V
Python?3.1
??
[root@localhost?p_b]#?cd?/root/
[root@localhost?~]#?python?-V
Python?3.6.1
??
如上可知,?第三种命令操作后,?切换的python版本只能在当前所在项目目录下生效!
在其他目录下就不会生效了!!
?
=============================================
如果要想卸载掉pyenv安装的python版本,?就使用"pyenv?uninstall?<version>"?命令
[root@localhost?~]#?pyenv?versions
??system
??2.7.5
??3.1
*?3.6.1?(set?by?/root/.pyenv/version)
?
[root@localhost?~]#?pyenv?uninstall?3.1
pyenv:?remove?/root/.pyenv/versions/3.1??y
?
[root@localhost?~]#?pyenv?versions????
??system
??2.7.5
*?3.6.1?(set?by?/root/.pyenv/version)

接下来稍微深入的了解下pyenv是如何进行python版本管理的?

使用which命令,可以看到,python命令已经不是本来的python命令,而是shims中的脚本文件
[root@localhost?~]#?which?python
/root/.pyenv/shims/python
[root@localhost?~]#?which?python3????????????????
/root/.pyenv/shims/python3
[root@localhost?~]#?which?pip3???????????????????
/root/.pyenv/shims/pip3

查看~/.pyenv/shims/python
[root@localhost?~]#?cat?/root/.pyenv/shims/python
#!/usr/bin/env?bash
set?-e
[?-n?"$PYENV_DEBUG"?]?&&?set?-x

program="${0##*/}"
if?[[?"$program"?=?"python"*?]];?then
??for?arg;?do
????case?"$arg"?in
????-c*?|?--?)?break?;;
????*/*?)
??????if?[?-f?"$arg"?];?then
????????export?PYENV_FILE_ARG="$arg"
????????break
??????fi
??????;;
????esac
??done
fi

export?PYENV_ROOT="/root/.pyenv"
exec?"/root/.pyenv/libexec/pyenv"?exec?"$program"?"$@"

可以看到python的命令最终被~/.pyenv/libexec/pyenv接管运行.?根据pyenv官方的解释,?大致了解到的意思是:
当使用的python命令被pyenv接管以后,到底使用哪个python版本,是由下面这些信息依次决定的:
1)?如果PYENV_VERSION这个变量存在,则使用这个变量里的版本;这个变量是由pyenv?shell?<version>配置的;
2)?按照往父目录查找的顺序查找直到根目录,第一个被查找到的.python-version文件作为版本文件,其指定的版本作为使用的python版本;
????这个文件使用pyenv?local?<version>配置
3)?$(pyenv?root)/version?这个文件若存在,则使用这个文件里制定的版本作为python版本;若不存在,则使用系统的版本;
????这个文件使用pyenv?global?<version>配置
4)?如果以上变量或文件都没有找到,就按照系统默认制定的python版本了。

另外,用户还可以在一个环境下同时配置多个版本的python;
回看一下上面pyenv?versions命令,输出的结果中会有一个set?by的提示,也向用户展示了,pyenv是基于什么指定的python版本。
[root@localhost?~]#?pyenv?versions
??system
??2.7.5
??3.1
*?3.6.1?(set?by?/root/.pyenv/version)

四.?python虚拟环境部署

为了对不同的项目进行隔离,使每个项目使用独立的python解释器及依赖,需要配置python虚拟环境.?
每个项目都有一个单独的python虚拟环境,?这样项目之前的python环境相互隔离,?便于使用和管理!

[root@localhost?~]#?pyenv?versions?????
??system
??2.7.5
*?3.6.1?(set?by?/root/.pyenv/version)

上面使用pyenv?install安装的python版本,比如3.6.1
python3.6.1解释器安装的路径为~/.pyenv/versions/3.6.1/;?
插件的安装的路径为~/.pyenv/versions/3.6.1/lib/python3.6/site-packages

[root@localhost?~]#?ll?-d?/root/.pyenv/versions/3.6.1/
drwxr-xr-x?6?root?root?4096?Dec?17?12:57?/root/.pyenv/versions/3.6.1/
[root@localhost?~]#?ll?-d?/root/.pyenv/versions/3.6.1/lib/python3.6/site-packages
drwxr-xr-x?8?root?root?4096?Dec?17?12:57?/root/.pyenv/versions/3.6.1/lib/python3.6/site-packages

使用pyenv- Virtual env创建python虚拟环境,实质上是在~/.pyenv/versions/3.6.1/下创建一个文件夹evns,存放该虚拟环境python的解释器;
并且在~/.pyenv/下创建一个软连接,该虚拟环境可以通过pyenv进行管理;

1)?比如创建某个项目的python虚拟环境,?虚拟环境的命令为kevin_py?(名称随便起),?该虚拟环境的python版本是2.7.5
[root@localhost?~]#?pyenv? Virtual env?2.7.5?kevin_py

查看,?发现在~/.pyenv/versions目录下会有一个kevin_py虚拟环境的软连接
[root@localhost?~]#?ll?~/.pyenv/versions/
total?8
drwxr-xr-x?7?root?root?4096?Dec?17?14:53?2.7.5
drwxr-xr-x?6?root?root?4096?Dec?17?12:57?3.6.1
lrwxrwxrwx?1?root?root???41?Dec?17?14:53?kevin_py?->?/root/.pyenv/versions/2.7.5/envs/kevin_py

查看python虚拟环境
[root@localhost?~]#?pyenv? Virtual envs
??2.7.5/envs/kevin_py?(created?from?/root/.pyenv/versions/2.7.5)
??kevin_py?(created?from?/root/.pyenv/versions/2.7.5)

有四种方法用于切换到python虚拟环境

1)?方法一??(推荐这一个切换方法)
[root@localhost?~]#?pyenv?activate?kevin_py
pyenv- Virtual env:?prompt?changing?will?be?removed?from?future?release.?configure?`export?PYENV_ Virtual ENV_DISABLE_PROMPT=1'?to?simulate?the?behavior.
(kevin_py)?[root@localhost?~]#?

2)?方法二??(这种切换方法也推荐)
[root@localhost?~]#?source?activate?kevin_py
pyenv- Virtual env:?activate?kevin_py
pyenv- Virtual env:?prompt?changing?will?be?removed?from?future?release.?configure?`export?PYENV_ Virtual ENV_DISABLE_PROMPT=1'?to?simulate?the?behavior.
(kevin_py)?[root@localhost?~]#?python?-V
Python?2.7.5
(kevin_py)?[root@localhost?~]#?

3)?方法三
[root@localhost?~]#?source?/root/.pyenv/versions/2.7.5/envs/kevin_py/bin/activate?kevin_py
(kevin_py)?[root@localhost?~]#?python?-V
Python?2.7.5
(kevin_py)?[root@localhost?~]#?

4)?方法三
[root@localhost?~]#?pyenv?shell?kevin_py
(kevin_py)?[root@localhost?~]#?python?-V
Python?2.7.5
(kevin_py)?[root@localhost?~]#?

使用"source?deactivate"?命令?或者?"pyenv?deactivate"命令?退出python虚拟环境!!!!!!
退出后,?在python虚拟环境里部署的应用程序不受影响!
(kevin_py)?[root@localhost?~]#?source?deactivate
pyenv- Virtual env:?deactivate?2.7.5/envs/kevin_py
[root@localhost?~]#

[root@localhost?~]#?pyenv?activate?kevin_py
pyenv- Virtual env:?prompt?changing?will?be?removed?from?future?release.?configure?`export?PYENV_ Virtual ENV_DISABLE_PROMPT=1'?to?simulate?the?behavior.
(kevin_py)?[root@localhost?~]#?pyenv?deactivate
[root@localhost?~]#?


2)?再创建另一个项目的python虚拟环境,?虚拟环境的命令为bobo_py,?该虚拟环境下的python版本为3.6.1
[root@localhost?~]#?pyenv? Virtual env?3.6.1?bobo_py

[root@localhost?~]#?ll?~/.pyenv/versions/
total?8
drwxr-xr-x?7?root?root?4096?Dec?17?14:53?2.7.5
drwxr-xr-x?7?root?root?4096?Dec?17?15:00?3.6.1
lrwxrwxrwx?1?root?root???40?Dec?17?15:00?bobo_py?->?/root/.pyenv/versions/3.6.1/envs/bobo_py
lrwxrwxrwx?1?root?root???41?Dec?17?14:53?kevin_py?->?/root/.pyenv/versions/2.7.5/envs/kevin_py

[root@localhost?~]#?pyenv? Virtual envs
??2.7.5/envs/kevin_py?(created?from?/root/.pyenv/versions/2.7.5)
??3.6.1/envs/bobo_py?(created?from?/root/.pyenv/versions/3.6.1)
??bobo_py?(created?from?/root/.pyenv/versions/3.6.1)
??kevin_py?(created?from?/root/.pyenv/versions/2.7.5)

先切换到bobo_py虚拟环境
[root@localhost?~]#?pyenv?activate?bobo_py
pyenv- Virtual env:?prompt?changing?will?be?removed?from?future?release.?configure?`export?PYENV_ Virtual ENV_DISABLE_PROMPT=1'?to?simulate?the?behavior.
(bobo_py)?[root@localhost?~]#?python?-V
Python?3.6.1
(bobo_py)?[root@localhost?~]#?

然后再从bobo_py环境环境切换到另一个虚拟环境kevin_py
(bobo_py)?[root@localhost?~]#?source?activate?kevin_py
pyenv- Virtual env:?activate?kevin_py
pyenv- Virtual env:?prompt?changing?will?be?removed?from?future?release.?configure?`export?PYENV_ Virtual ENV_DISABLE_PROMPT=1'?to?simulate?the?behavior.

退出虚拟环境
(kevin_py)?[root@localhost?~]#?source?deactivate
pyenv- Virtual env:?deactivate?2.7.5/envs/kevin_py
[root@localhost?~]#?

注意:?上面介绍的四种虚拟环境的切换方法,?强烈建议采用第一种和第二种切换方法!
因为采用前两种切换方法进去后,?使用"source?deactivate"?或者?"pyenv?deactivate"命令可以正常退出来!
如果采用后两种切换方法进去后,?使用"source?deactivate"?或者?"pyenv?deactivate"命令退不出来!

使用"pyenv? Virtual env-delete"命令?删除虚拟环境
[root@localhost?~]#?pyenv? Virtual envs
??2.7.5/envs/kevin_py?(created?from?/root/.pyenv/versions/2.7.5)
??3.6.1/envs/bobo_py?(created?from?/root/.pyenv/versions/3.6.1)
??bobo_py?(created?from?/root/.pyenv/versions/3.6.1)
??kevin_py?(created?from?/root/.pyenv/versions/2.7.5)

[root@localhost?~]#?pyenv? Virtual env-delete?bobo_py
pyenv- Virtual env:?remove?/root/.pyenv/versions/3.6.1/envs/bobo_py??y

[root@localhost?~]#?pyenv? Virtual envs???????????????
??2.7.5/envs/kevin_py?(created?from?/root/.pyenv/versions/2.7.5)
??kevin_py?(created?from?/root/.pyenv/versions/2.7.5)

查看更多关于Python多版本管理器-pyenv 介绍及部署记录的详细内容...

  阅读:37次