在 macOS 上使用 pyenv + pyenv-virtualenv 建立 Python 開發環境

kyo
·
·
IPFS
·
by Koma Zhang on Behance

「人生苦短,我用 Python」闡述了 Python 的易用與簡潔,但如果深入到 Python 的套件管理與版本隔離,則是一件十分複雜的事,有興趣的人可以參考下列內容:

本篇重點

這次並沒有要細論上述內容,寫作動機只是最近想把 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 ,在此先不討論。

Python Developers Survey 2020 Results by JetBrains

安裝 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.

CC BY-NC-ND 2.0 授权

喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!