在 macOS 上使用 pyenv + pyenv-virtualenv 建立 Python 開發環境
「人生苦短,我用 Python」闡述了 Python 的易用與簡潔,但如果深入到 Python 的套件管理與版本隔離,則是一件十分複雜的事,有興趣的人可以參考下列內容:
- 撥開 Python, pip, site-packages 的藍色蜘蛛網 💢
- 《捕蛇者說》Ep 15. 和 PyPA 的成員聊聊 Python 開發工作流(推薦!)
- 建立一個方便開發的 Python 環境 (零)- 使用 Pyenv 管理 Python 版本
- pip, pipenv 和 poetry 的選擇
本篇重點
這次並沒有要細論上述內容,寫作動機只是最近想把 Anaconda 這個初學 Python 時都一定知曉的工具移除掉,而我現在的 Python 虛擬環境都是用 conda 的 env 居多,自然要有替代方案,最常見的替代方案,就是 pyenv。
本篇僅記錄一下設定上的重點,詳細流程(其實也沒幾步)可搜尋「pyenv」或參考 pyenv 官方 GitHub 。
小提醒
Python 版本管理和套件的虛擬環境管理與隔離 基本上是兩件事,只不過 Anaconda 透過 conda 同時都能做到而已,而 pyenv 偏向 Python 版本管理,雖然你要直接當虛擬環境來用也未嘗不可,但還是推薦使用 virtualenv 較為合理。
為何要從 conda 轉向 pyenv?
倒沒什麼重大的原因,真要說的話,就是為了「簡潔」而已。
所有用 conda env 建立的虛擬環境都同時可以用 pip 或 conda 來安裝第三方套件,這樣容許混雜的模式讓我略感煩躁。
其次是 conda 的 base env 真的很肥大,畢竟幫你灌好了一堆資料科學套件,雖然方便,但這也是最常被垢病的部分,可謂雙面刃。
其他考慮但未採用的選項
我想要的是可以輕鬆全域、部分、單一專案使用與切換的選項。
比如幾個 Flask 專案可以共用一個環境就好;沒有特別指定的話,用安裝套件最少的通用環境;如果是精心製作的某專案,就需要一個專屬的環境。以上需求都要一次滿足。
- Python 內建的 venv:通常我是在特定的專案採用,因為沒有更高層的封裝讓你可以輕鬆跨專案打開,路徑要自己找,比較適合單一專案使用。
- pipenv、poetry 等套件管理工具:前者小荒廢,後者還很新,主要的亮點都是在處理套件之間的相互依賴問題,現階段暫時不考慮。
以上都只是套件管理,如果要連同 Python 的版本一起管理(這顯然是個硬需求),還是需要 pyenv。另外,以容器建立開發環境也是一個趨勢,比如 VS Code 的 DevContainer ,在此先不討論。
安裝 pyenv 與 pyenv-virtualenv
brew update brew install pyenv brew install pyenv-virtualenv
裝完之後要設定一下 .bashrc 或 .zshrc,還有 .bash_profile 或 .zprofile,端視你的 shell 是哪個。
設定的內容主要是提供正確的 Python PATH,這部分很關鍵。具體要新增什麼內容,各教學或官方的版本沒有完全一致,不過大同小異,在此提供我實際新增的部分:
.zshrc 新增
if command -v pyenv 1>/dev/null 2>&1; then eval "$(pyenv init -)" fi
特別說明,官方教學只說需要新增中間的 eval "$(pyenv init -)"
,但我光這樣設定,會無法切換全域 Python 版本,看了 這篇 之後改成上述的版本。
.zprofile 新增
echo 'eval "$(pyenv init --path)"' >> ~/.zprofile
你可能跟我一樣一開始也沒有這個檔,直接用官方給的指令新增就好:
設定好後記得要分別 source 一下。
簡單設定與使用
以我的例子:
#1 pyenv install 3.7.11 pyenv global 3.7.11 # 將全域的 Python 版本設為 3.7.11 #2 pyenv virtualenv 3.7.11 my_venv<自行命名>
如果已經在 pyenv 的 3.7.11 環境下,則上述 #2 的 3.7.11
可以省略,只要 pyenv virtualenv my_venv
即可建立虛擬環境。
啟用與停止虛擬環境
pyenv activate my_venv pyenv deactivate my_venv
移除虛擬環境
pyenv uninstall my_venv
查看目前所有虛擬環境
pyenv virtualenvs
你會看到每一個虛擬環境都有兩個項目,這是正常的:
There are two entries for each virtualenv, and the shorter one is just a symlink.
像下面這樣:
3.7.11/envs/my_venv (created from /Users/kyo/.pyenv/versions/3.7.11) * my_venv (created from /Users/kyo/.pyenv/versions/3.7.11)
小結
使用 pyenv 建立不同 Python 版本並管理相對應的虛擬環境實在非常方便!
附帶一提,雖然不一定要安裝 pyenv-virtualenv 而可以直接 pip virtualenv
即可,但後者的使用方式類似內建的 venv,比較沒有那麼彈性。
此外,pyenv-virtualenv 在 3.3 版本以上的 Python,實際上就是調用內建的 venv 來建立虛擬環境,否則就是調用 virtualenv,總之就是多一層封裝讓使用變得更方便而已。
參考
Originally published at Code and Me on July 10, 2021.