Pyenv
簡介
-
首先,該工具是在類linux環境中的工具,在windows系統下是不支持的。(tips: win10現在支持linux子系統利用WSL,可以非常方便在windows上使用linux系統,自行google)
-
然后,工具主要作用是解決一個比較棘手的問題,就是多個python版本的使用。無論是pytho2還是python3包括多個版本之間的使用上。試想下,同一系統環境中,多個項目使用的不同的python版本,那么在啟動項目時,使用的python版本的指定就成了必須明確指定,且不同版本所使用的第三方包管理工具的版本也需要明確指定使用。
因此,要解決這種繁瑣的操作,pyenv由此誕生,其就借鑒了Ruby的多版本環境下的管理模式。既然是一種模式,那就套用這種模式。模式設計描述大致如下:- 利用shell啟動加載,初始化工具。
- 利用linux系統的三大作用域,system wild/user's home/project_or_instance directory ,也就是 系統作用域(在apphome目錄)/用戶作用域(shell 環境變量)/ 單個項目或者叫實例目錄(目錄下的.python-version文件中描述)/ 。
- 一切python及其官方自帶工具或腳本,運行都會隱晦的通過pyenv調用,使用者無感知。原理如下條:
- pyenv的命令操作,就是依據三層. 首先是一個環境變量PYENV_VERSION(通過pyenv shell管理它),優先級第一;然后是每個app或者project目錄下的.python-version(通過pyenv local管理它,沒有則從當前目錄向上找,直到找到根目錄)。最后是系統層面,就是pyenv_root/version文件,系統層面的文件時放在pyenv安裝目錄的(一般是~/.pyenv/)。如果連version中都沒有,那么就依據無pipenv狀態下的python執行。
- 依據上面規則,依次排查判斷,以此最終確定本次執行的命令是確定的python版本。
-
小結: 其實說白了,就是基於path查找命令優先級為基礎,強行在path前面插入一個pyenv_root/shims的目錄(里面有偽造的python/pip/setuptools等命令的同名腳本,有興趣可以看下腳本內容)。然后執行這些偽造命令,其實都是在執行pyenv命令,這些偽造的命令會作為參數傳遞給pyenv命令,然后執行pyenv命令。然后pyenv命令,根據當前shell所在的上下文(也就是依據三層判定規則),決定出使用哪個版本的python和偽造的參數名同名的命令,來具體執行。而python版本需要通過pyenv install安裝到pyenv_root/version/目錄下,這樣才能找到最能匹配的版本。這里最重要的一點其實就是上下文環境了,根據上下文環境確定出正確的version版本,這個version版本而且不是某一個確定的,還可以是一個優先級順序列表。如: 3.7.0 3.5.6 2.7 ...
博文圖片掛了臨時解決辦法
安裝pyenv
- 前提,只能在類linux系統中使用
- 安裝,執行命令:curl https://pyenv.run | bash
- 配置, 根據提示,在~/.bashrc文件最后,追加以下shell命令:
export PATH="/root/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
-
斷開shell會話,再連接一個,使新添加export命令加載生效。
-
就可以開始使用pyenv
通過pyenv安裝python各種發行版
- 首先,pyenv是將現有支持的python各python發行版版本信息保存到pyenv本地的。如果發現沒有自己的版本可以先通過命令更新本地信息,已達到支持當前版本需求。具體操作參看下面的常用命令。
- 然后,通過pyenv install --list|grep 出自己想要的版本。如:pyenv install --list|grep 3.7.0
- 其次,要知道pyenv安裝python也是通過一個叫做pyenv-build的pyenv插件完成的。對pyenv-build感興趣點擊click me, pyenv-build pyenv-build 也是可以單獨執行使用的命令。
- 再,通過pyenv安裝過程如下:
可以看到,是從pyenv也是官方網站下載編譯安裝的。warning提示的是害怕通過pyenv安裝的python會使用提示的文件中的配置,從而影響新安裝的python使用其中的配置,脫離了pyenv對python版本的管理目的。
Tips: 新手要明確一個概念,使用pyenv時是從python發行版的官網新安裝的,和現有系統中的python版本沒有一點關系,當前系統的舊版本依然好好的呆在它原來的位置。有了pyenv,系統有的舊版本被pyenv當作system版本來看待。pyenv安裝的新版本都是放在了~/.pyenv/versions/目錄下的。pyenv根據其設計原理就使用versions目錄下的正確版本了。 - 最后,pyenv安裝python就沒有了神秘感;不過需要注意的是NOTICE:通過pyenv安裝python,還是要根據不同環境需要提前安裝依賴的,安裝依賴查看pyenv安裝python依賴
pyenv命令
常用命令
- pyenv commands 查看所有子命令
- pyenv install --list 查看所有可安裝的python發行版
- 更新可用python發行版,執行命令: cd /root/.pyenv/plugins/python-build/../.. && git pull && cd -
- pyenv install 3.7.1 安裝指定的發行版,這里舉例是安裝3.7.1
- pyenv version 根據上下文,打印出當前環境下使用的python 版本。其中如果打印的是"system (set by /root/.pyenv/version)",表示pyenv沒有獲取到應該使用的版本,就會使用原系統path中的python。
- pyenv versions 展示當前pyenv可用的python版本,前面有星號的表示當前上下文下會使用的python版本。如圖示:有兩個版本,system代表系統的,非pyenv安裝的版本;而3.7.0就是我通過pyenv install 3.7.0 安裝的版本。
- pyenv which python3.7 獲取which后面指定的命令的full path,經常用到的自省命令。
- pyenv whence 2to3 列出指定命令在哪些版本中存在,也是經常用到的自省命令。
- pyenv local 3.7.0 在當前目錄下,設置當前目錄的使用python版本。設置是記錄在當前目錄下一個.python-version的文件中,該文件由pyenv local 自動生成。
可以看到操作后,在hello目錄環境下,再執行pyenv version 可以看出python版本使用的是3.7.0了。前后對比可以看出pyenv對python版本管理的效果。
除此之外,local后面還可以設置多個版本,版本間以空格間隔,多個版本間的順序依次降低優先級。也就是現在前面的版本中查找,然后再后面的版本中查找。非常兼容使用tox運行py2和py3雜合的項目。 - pyenv local --unset 刪除當前目錄下local環境,即刪除了.python-version文件
- pyenv global 3.7.0 設置3.7.0 為全局版本,信息寫入到pyenv目錄下的version文件中;如果該命令后沒有跟python發行版本這是返回當前全局版本。
- pyenv shell 3.7.0 設置當前會話PYENV_VERSION環境變量為3.7.0;如果不跟版本則打印當前PYENV_VERSION的版本。
- pyenv uninstall version 卸載某個版本的python
- pyenv rehash 安裝新版本后執行,使生效.
多版本Python的管理
使用pyenv就要通過pyenv來安裝python版本了
安裝示例:
- pyenv install 3.7.0
- 新建項目,在項目目錄下設置項目使用的python版本:
- mkdir new_project
- cd new_project
- pyenv local 3.7.0
- 這樣在new_project 目錄下使用python的其他命令,如pipenv或者pip等都是使用3.7.0版本python對應的版本工具了。
- 再new_project 目錄下使用pip安裝django
- pip install django
- pip freeze > requirements.txt 生成requirments.txt文件
- 如果再使用某個命令上有什么疑問,使用pyenv which +命令名 查看當前環境下使用的命令是不是對應的版本下的。特別是通過pyenv安裝的python3.7 沒有pipenv命令,有時候就使用了system下的,導致使用了錯誤版本非3.7版本的pipenv初始化項目了。所以所使用pyenv which來確定命令是否使用正確的版本。
小結: 上面也提到了,使用pipenv。其實pyenv + pipenv 的結合使用,是非常棒的一個組合。前者進行python版本管理和切換,后者對python依賴包及獨立虛擬環境的管理。具體pipenv的使用介紹查看另一篇文章。這里要特別注意,在使用pipenv install 時要指定--python版本與 pyenv version一致,因為pipenv 是不會自動使用pyenv_root/shims中命令的。