1. 程式人生 > >Python多版本管理器-pyenv 介紹及部署記錄

Python多版本管理器-pyenv 介紹及部署記錄

一. pyenv簡單介紹

由於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安裝

該指令碼下載地址: 

可以到Linux公社資源站下載:

------------------------------------------分割線------------------------------------------

具體下載目錄在 /2019年資料/1月/2日/Python多版本管理器-pyenv 介紹及部署記錄/

------------------------------------------分割線------------------------------------------
     
執行指令碼進行安裝(執行前授予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安裝到系統環境變數中。
[[email protected] ~]# ll -d /root/.pyenv
drwxr-xr-x 11 root root 4096 Dec 17 10:48 /root/.pyenv
 
在~/.bash_profile檔案底部新增下面三行內容, 讓系統可以找到 pyenv 安裝的 Python
[[email protected] ~]# vim ~/.bash_profile     
export PATH="/root/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
 
使上面配置生效
[[email protected] ~]# source ~/.bash_profile
 
檢視pyenv安裝情況
[[email protected] ~]# pyenv --version            //或者"pyenv -v"
pyenv 1.2.8
 
更新pyenv
[[email protected] ~]# pyenv update
 
3) 解除安裝pyenv
先刪除pyenv的安裝目錄,  這裡即是/root/.pyenv
[[email protected] ~]# rm -fr /root/.pyenv
 
接著刪除~/.bash_profile裡面配置的系統環境變數
[[email protected] ~]# vim ~/.bash_profile     //刪除下面三行
export PATH="/root/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
 
[[email protected] ~]# source ~/.bash_profile
 
這樣pyenv就被解除安裝了, 解除安裝pyenv後, 當前終端shell裡會出現"-bash: pyenv: command not found"
的提示資訊, 不過不影響使用. 再開啟其他的終端視窗, 就不會出現該提示資訊.

2) pyenv使用

當前系統預設的Python版本
[[email protected] ~]# python -V
Python 2.6.6
 
pyenv的命令,可以通過pyenv help檢視
[[email protected] ~]# 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版本
[[email protected] ~]# 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可檢測到的所有版本,處於啟用狀態的版本前以 * 標示.
[[email protected] ~]# pyenv versions
* system (set by /root/.pyenv/version)
 
使用pyenv install  <version> 安裝python,可以使用-v引數,檢視安裝過程。
如下, 分別安裝三個版本的python
[[email protected] ~]# pyenv install -v 2.7.5
[[email protected] ~]# pyenv install -v 3.1
[[email protected] ~]# pyenv install -v 3.6.1
 
檢視當前pyenv可檢測到的python版本 (即pyenv當前安裝了哪些python版本)
[[email protected] ~]# pyenv versions
* system (set by /root/.pyenv/version)
  2.7.5
  3.1
  3.6.1
 
檢視當前pyenv使用的python版本  (注意是version, 而不是上面的versions)
[[email protected] ~]# 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, 則需要下面命令進行切回操作!!!!!!
[[email protected] p_b]# pyenv local system
[[email protected] p_b]# python -V       
Python 2.6.6
 
下面分別介紹下pyenv這三個基礎命令切換python���本的操作
a) 使用pyenv global <version>配置當前使用者的系統使用的python版本
[[email protected] ~]# pyenv versions
* system (set by /root/.pyenv/version)
  2.7.5
  3.1
  3.6.1
 
[[email protected] ~]# python -V
Python 2.6.6
 
使用下面命令進行python版本的切換
[[email protected] ~]# pyenv global 3.6.1
 
[[email protected] ~]# pyenv versions
  system
  2.7.5
  3.1
* 3.6.1 (set by /root/.pyenv/version)
 
[[email protected] ~]# python -V
Python 2.6.6
 
需要執行下面命令進行資料庫更新後, pyenv切換的python版本才會生效!
[[email protected] ~]# pyenv rehash
 
[[email protected] ~]# python -V       
Python 3.6.1
 
[[email protected] ~]# which python
/root/.pyenv/shims/python
 
b) 使用pyenv shelll <version>配置當前shell的python版本,退出shell則失效
[[email protected] ~]# python -V
Python 3.6.1
[[email protected] ~]# pyenv versions
  system
  2.7.5
  3.1
* 3.6.1 (set by /root/.pyenv/version)
[[email protected] ~]# pyenv shell 2.7.5
[[email protected] ~]# python -V     
Python 2.7.5
 
如上設定後, 只在當前shell終端視窗有效, 退出重新登入 或 再開啟另外一個視窗就不生效了 (即pytho版本還是之前的)
即使執行"pyenv rehash" 進行更新操作, 在別的shell視窗也是不生效的!
 
當前shell下,取消配置的使用python shell --unset;若退出此shell,配置也會失效。
[[email protected] ~]# pyenv shell --unset
[[email protected] ~]# python -V       
Python 3.6.1
 
c) 使用pyenv local <version>配置所在專案(目錄)的python版本
新建一個資料夾~/project,在此資料夾下使用python local <version>
[[email protected] ~]# python -V 
Python 3.6.1
[[email protected] ~]# mkdir project
[[email protected] ~]# cd project/
[[email protected] project]# pyenv local 3.1
[[email protected] project]# pyenv versions
  system
  2.7.5
* 3.1 (set by /root/project/.python-version)
  3.6.1
 
在當前專案目錄下檢視python版本
[[email protected] project]# python -V
Python 3.1
 
新建目錄~/project/p_a,切換到~/project/p_a,並檢視版本
[[email protected] project]# mkdir p_a&& cd p_a
[[email protected] p_a]# python -V
Python 3.1
 
[[email protected] p_b]# cd /root/
[[email protected] ~]# python -V
Python 3.6.1
 
如上可知, 第三種命令操作後, 切換的python版本只能在當前所在專案目錄下生效!
在其他目錄下就不會生效了!!
 
=============================================
如果要想解除安裝掉pyenv安裝的python版本, 就使用"pyenv uninstall <version>" 命令
[[email protected] ~]# pyenv versions
  system
  2.7.5
  3.1
* 3.6.1 (set by /root/.pyenv/version)
 
[[email protected] ~]# pyenv uninstall 3.1
pyenv: remove /root/.pyenv/versions/3.1? y
 
[[email protected] ~]# pyenv versions   
  system
  2.7.5
* 3.6.1 (set by /root/.pyenv/version)

接下來稍微深入的瞭解下pyenv是如何進行python版本管理的?

使用which命令,可以看到,python命令已經不是本來的python命令,而是shims中的指令碼檔案
[[email protected] ~]# which python
/root/.pyenv/shims/python
[[email protected] ~]# which python3               
/root/.pyenv/shims/python3
[[email protected] ~]# which pip3                 
/root/.pyenv/shims/pip3
 
檢視~/.pyenv/shims/python
[[email protected] ~]# 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" "[email protected]"
 
可以看到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版本。
[[email protected] ~]# pyenv versions
  system
  2.7.5
  3.1
* 3.6.1 (set by /root/.pyenv/version)

四. python虛擬環境部署

為了對不同的專案進行隔離,使每個專案使用獨立的python直譯器及依賴,需要配置python虛擬環境.
每個專案都有一個單獨的python虛擬環境, 這樣專案之前的python環境相互隔離, 便於使用和管理!
 
[[email protected] ~]# 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
 
[[email protected] ~]# 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/
[[email protected] ~]# 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
[[email protected] ~]# pyenv virtualenv 2.7.5 kevin_py
 
檢視, 發現在~/.pyenv/versions目錄下會有一個kevin_py虛擬環境的軟連線
[[email protected] ~]# 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虛擬環境
[[email protected] ~]# 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) 方法一  (推薦這一個切換方法)
[[email protected] ~]# 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) [[email protected] ~]#
 
2) 方法二  (這種切換方法也推薦)
[[email protected] ~]# 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) [[email protected] ~]# python -V
Python 2.7.5
(kevin_py) [[email protected] ~]#
 
3) 方法三
[[email protected] ~]# source /root/.pyenv/versions/2.7.5/envs/kevin_py/bin/activate kevin_py
(kevin_py) [[email protected] ~]# python -V
Python 2.7.5
(kevin_py) [[email protected] ~]#
 
4) 方法三
[[email protected] ~]# pyenv shell kevin_py
(kevin_py) [[email protected] ~]# python -V
Python 2.7.5
(kevin_py) [[email protected] ~]#
 
使用"source deactivate" 命令 或者 "pyenv deactivate"命令 退出python虛擬環境!!!!!!
退出後, 在python虛擬環境裡部署的應用程式不受影響!
(kevin_py) [[email protected] ~]# source deactivate
pyenv-virtualenv: deactivate 2.7.5/envs/kevin_py
[[email protected] ~]#
 
[[email protected] ~]# 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) [[email protected] ~]# pyenv deactivate
[[email protected] ~]#
 
 
2) 再建立另一個專案的python虛擬環境, 虛擬環境的命令為bobo_py, 該虛擬環境下的python版本為3.6.1
[[email protected] ~]# pyenv virtualenv 3.6.1 bobo_py
 
[[email protected] ~]# 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
 
[[email protected] ~]# 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虛擬環境
[[email protected] ~]# 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) [[email protected] ~]# python -V
Python 3.6.1
(bobo_py) [[email protected] ~]#
 
然後再從bobo_py環境環境切換到另一個虛擬環境kevin_py
(bobo_py) [[email protected] ~]# 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) [[email protected] ~]# source deactivate
pyenv-virtualenv: deactivate 2.7.5/envs/kevin_py
[[email protected] ~]#
 
注意: 上面介紹的四種虛擬環境的切換方法, 強烈建議採用第一種和第二種切換方法!
因為採用前兩種切換方法進去後, 使用"source deactivate" 或者 "pyenv deactivate"命令可以正常退出來!
如果採用後兩種切換方法進去後, 使用"source deactivate" 或者 "pyenv deactivate"命令退不出來!
 
使用"pyenv virtualenv-delete"命令 刪除虛擬環境
[[email protected] ~]# 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)
 
[[email protected] ~]# pyenv virtualenv-delete bobo_py
pyenv-virtualenv: remove /root/.pyenv/versions/3.6.1/envs/bobo_py? y
 
[[email protected] ~]# 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)