在 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.
Like my work? Don't forget to support and clap, let me know that you are with me on the road of creation. Keep this enthusiasm together!