一. pyenv簡單介紹python
在平常運維中, 常常遇到這樣的狀況: 系統自帶的Python是2.x,而業務部署須要Python 3.x 環境, 此時須要在系統中安裝多個Python版本,但又不能影響系統自帶的Python 版本,即須要實現Python的多版本環境共存, pyenv就是這樣一個Python版本管理器, 能夠同時管理多個python版本共存! 簡單的說,pyenv 能夠根據需求使用戶在系統裏安裝和管理多個Python 版本:
- 配置當前用戶的python的版本;
- 配置當前shell的python版本;
- 配置某個項目(目錄及子目錄)的python版本;
- 配置多個虛擬環境.git
因爲python的各類優勢,當前學習及使用python的人愈來愈多, 學習python有一個不容忽視的問題就是python的版本問題! 到如今爲止,python的版本有不少,可是問題在於python2與python3的區別。python3的對一些模塊進行了改變,致使了python2寫的代碼有的不被python3兼容,從而致使程序運行報錯。所以,在學習和工做中使用python的時候,最好是安裝一個pyenv管理器, 多安裝幾個python版本進行管理, 而後再針對不一樣項目安裝各自項目的python虛擬環境, 相互隔離, 這樣便於使用和管理。github
二. pyenv工做原理sql
pyenv是利用系統環境變量PATH的優先級,劫持python的命令到pyenv上,根據用戶所在的環境或目錄,使用不一樣版本的python。shell
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安裝和使用說明vim
1) pyenv安裝centos
[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.com/pyenv/pyenv-installer 推薦採用The automatic installer的方式安裝,能夠一鍵安裝pyenv的全部插件。 [root@localhost ~]# curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash pyenv套件下插件: - pyenv-doctor - pyenv-installer - pyenv-update - pyenv-virtualenv - pyenv-which-ext ================================================================================== 舒適提示: 以上https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer的訪問內容 , 能夠將內容粘出來放在服務器的一個shell腳本文件中, 而後執行該腳本用以安裝pyenv 該腳本下載地址: https://pan.baidu.com/s/1wW9ylrmc4Q9wxu_i3-1wYA 提取密碼: rhtj 執行腳本進行安裝(執行前授予755權限) # chmod 755 pyenv-installer # /bin/bash pyenv-installer ================================================================================= 分析一下上面的pyenv-installer腳本,能夠發如今centos上,其實它作了如下事情: git clone --depth 1"git://github.com/pyenv/pyenv.git" "${HOME}/.pyenv" git clone --depth 1"git://github.com/pyenv/pyenv-doctor.git" "${HOME}/.pyenv/plugins/pyenv-doctor" git clone --depth 1"git://github.com/pyenv/pyenv-installer.git" "${HOME}/.pyenv/plugins/pyenv-installer" git clone --depth 1"git://github.com/pyenv/pyenv-update.git" "${HOME}/.pyenv/plugins/pyenv-update" git clone --depth 1"git://github.com/pyenv/pyenv-virtualenv.git""${HOME}/.pyenv/plugins/pyenv-virtualenv" git clone --depth 1"git://github.com/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 virtualenv-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 virtualenv-init -)" [root@localhost ~]# source ~/.bash_profile 這樣pyenv就被卸載了, 卸載pyenv後, 當前終端shell裏會出現"-bash: pyenv: command not found" 的提示信息, 不過不影響使用. 再打開其餘的終端窗口, 就不會出現該提示信息.
2) pyenv使用bash
當前系統默認的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.com/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-virtualenv建立python虛擬環境,實質上是在~/.pyenv/versions/3.6.1/下建立一個文件夾evns,存放該虛擬環境python的解釋器; 而且在~/.pyenv/下建立一個軟鏈接,該虛擬環境能夠經過pyenv進行管理; 1) 好比建立某個項目的python虛擬環境, 虛擬環境的命令爲kevin_py (名稱隨便起), 該虛擬環境的python版本是2.7.5 [root@localhost ~]# pyenv virtualenv 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 virtualenvs 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-virtualenv: prompt changing will be removed from future release. configure `export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior. (kevin_py) [root@localhost ~]# 2) 方法二 (這種切換方法也推薦) [root@localhost ~]# source activate kevin_py pyenv-virtualenv: activate kevin_py pyenv-virtualenv: prompt changing will be removed from future release. configure `export PYENV_VIRTUALENV_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-virtualenv: deactivate 2.7.5/envs/kevin_py [root@localhost ~]# [root@localhost ~]# pyenv activate kevin_py pyenv-virtualenv: prompt changing will be removed from future release. configure `export PYENV_VIRTUALENV_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 virtualenv 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 virtualenvs 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-virtualenv: prompt changing will be removed from future release. configure `export PYENV_VIRTUALENV_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-virtualenv: activate kevin_py pyenv-virtualenv: prompt changing will be removed from future release. configure `export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior. 退出虛擬環境 (kevin_py) [root@localhost ~]# source deactivate pyenv-virtualenv: deactivate 2.7.5/envs/kevin_py [root@localhost ~]# 注意: 上面介紹的四種虛擬環境的切換方法, 強烈建議採用第一種和第二種切換方法! 由於採用前兩種切換方法進去後, 使用"source deactivate" 或者 "pyenv deactivate"命令能夠正常退出來! 若是採用後兩種切換方法進去後, 使用"source deactivate" 或者 "pyenv deactivate"命令退不出來! 使用"pyenv virtualenv-delete"命令 刪除虛擬環境 [root@localhost ~]# pyenv virtualenvs 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 virtualenv-delete bobo_py pyenv-virtualenv: remove /root/.pyenv/versions/3.6.1/envs/bobo_py? y [root@localhost ~]# pyenv virtualenvs 2.7.5/envs/kevin_py (created from /root/.pyenv/versions/2.7.5) kevin_py (created from /root/.pyenv/versions/2.7.5)