python多版本管理

python多版本管理

背景

python2.x 已經(jīng)停止維護(hù),日常開發(fā)中一般都使用 python3.x 的版本,然而考慮到部分舊的腳本是用 python2.x 寫的,因此同時在機(jī)器上維護(hù)多份不同的 python 版本是非常常見的現(xiàn)象。那么如何更好地管理和切換不同的 python 版本便成了一個有待解決的問題?

經(jīng)常被多個版本困擾的我,今天好好查閱了一番,發(fā)現(xiàn) pyenv 是一個不錯的選擇,現(xiàn)將相關(guān)內(nèi)容記錄如下,以供查閱。

備注: 筆者使用的是MacOS,所以后續(xù)操作均基于MacOS。

安裝pyenv

pyenv 是一個 python 版本管理工具,具備方便、快捷地安裝、管理多個 python 版本,并在不同 python 版本間進(jìn)行切換的能力。

安裝pyenv

使用 homebrew 安裝 pyenv,在終端中輸入如下命令,該命令會自動下載最新版本的 pyenv,并自動下載依賴包。

brew install pyenv

安裝完成后,可運(yùn)行which pyenv命令查看pyenv是否存在。

pyenv工作原理

pyenv 會在系統(tǒng)環(huán)境變量 PATH 前面插入一個墊片目錄 (pyenv root)/shims,這樣每當(dāng)運(yùn)行 python 命令時,pyenv 便會攔截到該命令,并調(diào)用當(dāng)前環(huán)境下使用的 python 版本對應(yīng)的該命令。

通過重新哈希,pyenv 會在目錄中維護(hù)一個 shims,從而將每一個 python 命令映射為不同 python 版本下的相應(yīng)命令。

shim 是一個輕量級的可執(zhí)行文件,它的主要任務(wù)是將終端輸入的 python 命令傳遞給 pyenv。

在安裝有 pyenv 的機(jī)器上,輸入 python 命令時(如pip),操作系統(tǒng)會執(zhí)行如下操作:

  1. 在 PATH 指向的目錄中查找名為 pip 的可執(zhí)行文件;
  2. 在 PATH 起始位置找到名為 pip 的 pyenv shim;
  3. 運(yùn)行名為 pip 的 shim,以告知 pyenv 運(yùn)行的 python 命令;
  4. pyenv 查找當(dāng)前環(huán)境對應(yīng)的 python 版本中的 pip 命令,并運(yùn)行。

為了在每次啟動 shell 的時候都能自動將 python 墊片目錄添加到 PATH 前面,可在/.bash_profile(或/.zshrc)末尾添加如下命令,在終端執(zhí)行如下命令即可:

# 檢測 pyenv 是否存在,若存在,則執(zhí)行 pyenv init 命令
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bash_profile

更新pyenv

brew upgrade pyenv

卸載pyenv

如果只是暫時不想使用 pyenv 的話,可考慮將/.bash_profile(或/.zshrc)文件中的pyenv init命令注釋掉,這樣可隨時通過取消注釋開啟 pyenv 功能。

如果想完全卸載 pyenv,則可按如下步驟操作:

# 刪除 pyenv 根目錄,同時會將所有安裝在$(pyenv root)/versions/目錄下的 python 版本刪除
rm -rf $(pyenv root)

# 卸載 pyenv
brew uninstall pyenv

pyenv常用命令

pyenv 常用命令可在Command Reference查詢。

pyenv commands

列出所有可用的pyenv命令。

$ pyenv commands
--version
commands
completions
exec
global
help
hooks
init
install
local

pyenv install

安裝指定 python 版本,通過 python-build命令安裝。

# 列出所有可用的版本
pyenv install -l
pyenv install --list

$ pyenv install -l
Available versions:
  2.1.3
  2.2.3
  2.3.7
  2.4.0
  2.4.1
  2.4.2
  2.4.3
# 安裝指定 python 版本
pyenv install [-f] [-kvp] <version>

# 選項說明
-f/--force: 強(qiáng)制安裝,即使該版本已經(jīng)安裝過了
-v/--verbose: 輸出安裝過程中的詳細(xì)信息
-g/--debug: 構(gòu)建 debug 版本
-s/--skip-existing: 跳過已安裝的版本

# 安裝 python 3.8.2
$ pyenv install 3.8.2
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Downloading Python-3.8.2.tar.xz...
-> https://www.python.org/ftp/python/3.8.2/Python-3.8.2.tar.xz
Installing Python-3.8.2...
python-build: use readline from homebrew
python-build: use zlib from xcode sdk
Installed Python-3.8.2 to /Users/Lilac/.pyenv/versions/3.8.2

pyenv uninstall

卸載指定 python 版本。

# 卸載指定 python 版本
pyenv uninstall [-f|--force] <version>

# 選項說明
-f/--force: 強(qiáng)制卸載,當(dāng)待卸載版本存在時,無需確認(rèn),當(dāng)待卸載版本不存在時,不顯示錯誤信息

# 卸載 python 3.8.2
$ pyenv uninstall 3.8.2
pyenv: remove /Users/Lilac/.pyenv/versions/3.8.2? y

$ pyenv versions
  system
  3.7.0

pyenv local

設(shè)置當(dāng)前工作目錄下的 python 版本。

pyenv local命令執(zhí)行后會在當(dāng)前工作目錄下的.python-version文件中寫入設(shè)入的 python 版本。

在當(dāng)前工作目錄執(zhí)行 python 命令時,會優(yōu)先使用pyenv local命令指定的 python 版本。

# 設(shè)置當(dāng)前工作目錄下用 python3.8.2
$ pyenv local 3.8.2

# 重置當(dāng)前目錄的 python 版本
$ pyenv local --unset

# 同時設(shè)置多個當(dāng)前工作目錄可用的 python 版本,如 python2.7.16 和 python3.8.2
# 注意:此時會優(yōu)先使用 python2.7.16
$ pyenv local 2.7.16 3.8.2

# 顯示當(dāng)前 pyenv 支持的 python 版本,該命令后文會介紹
$ pyenv versions
  system
* 2.7.16 (set by /Users/Lilac/.python-version)
* 3.8.2 (set by /Users/Lilac/.python-version)

$ python --version
Python 2.7.16
$ python2.7 --version
Python 2.7.16
$ python3.8 --version
Python 3.8.2

pyenv global

設(shè)置全局 python 版本。

pyenv global命令執(zhí)行后會在~/.python-version文件中寫入設(shè)入的 python 版本。

# 示例
# 設(shè)置全局 python 版本為 python3.8.2
$ pyenv global 3.8.2

# 示例
# 同時設(shè)置多個全局 python 版本,如 python2.7.16 和 python3.8.2
# 注意:此時會優(yōu)先使用 python2.7.16
$ pyenv global 2.7.16 3.8.2         
$ pyenv versions
  system
* 2.7.16 (set by /Users/Lilac/.python-version)
* 3.8.2 (set by /Users/Lilac/.python-version)
$ python --version
Python 2.7.16
$ python2.7 --version
Python 2.7.16
$ python3.8 --version
Python 3.8.2

pyenv shell

設(shè)置當(dāng)前 shell 窗口使用的 python 版本。

實(shí)現(xiàn)方式:通過設(shè)置當(dāng)前 shell 窗口的 PYENV_VERSION 環(huán)境變量實(shí)現(xiàn)。

python版本設(shè)置優(yōu)先級:pyenv shell > pyenv local > pyenv global

即 pyenv 會優(yōu)先使用當(dāng)前 shell 窗口設(shè)置的 python 版本(pyenv shell),如果當(dāng)前窗口未設(shè)置的話,則使用當(dāng)前工作目錄設(shè)置的 python 版本(pyenv local),如果當(dāng)前工作目錄也未設(shè)置,則使用全局 python 版本(pyenv global)。

# 設(shè)置當(dāng)前 shell 窗口 python 版本為2.7.16
$ pyenv shell 2.7.16

# 顯示當(dāng)前 shell 窗口使用的 python 版本
$ pyenv shell
2.7.16

# 重置當(dāng)前 shell 窗口的 python 版本
$ pyenv shell --unset

# 同時設(shè)置多個當(dāng)前 shell 窗口可用的 python 版本,如 python2.7.16 和 python3.8.2
# 注意:此時會優(yōu)先使用 python2.7.16
$ pyenv shell 2.7.16 3.8.2      
$ pyenv versions
  system
* 2.7.16 (set by PYENV_VERSION environment variable)
* 3.8.2 (set by PYENV_VERSION environment variable)
$ python --version
Python 2.7.16
$ python2.7 --version
Python 2.7.16
$ python3.8 --version
Python 3.8.2

pyenv version

顯示當(dāng)前使用的 python 版本,同時會顯示該版本是如何設(shè)置進(jìn)來的(pyenv global/pyenv local/pyenv shell)。

pyenv version

$ pyenv version
3.8.2 (set by PYENV_VERSION environment variable)

pyenv versions

列出所有 pyenv 已知的 python 版本,當(dāng)前使用的版本會在前面用*號標(biāo)明

pyenv versions

$ pyenv versions
    system
  3.7.0
* 3.8.2 (set by PYENV_VERSION environment variable)

pyenv rehash

更新墊片目錄 shims 內(nèi)容,以使 pyenv 知道它所管理的 python 版本信息,一般在安裝完一個新版本的 python 后,需運(yùn)行一次該命令。

$ pyenv rehash

pyenv which

顯示當(dāng)前命令的可執(zhí)行文件所在的完整路徑。

pyenv which

$ pyenv which python3
/Users/Lilac/.pyenv/versions/3.8.2/bin/python3

參考文章

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容