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

kyo
Code and Me
Published in
6 min readJul 10, 2021
by Koma Zhang

「人生苦短,我用 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 https://blog.kyomind.tw on July 10, 2021.

--

--