有了 pyenv 可以管理不同 Python 版本後, 搭配 venv 建立虛擬環境雖然很不錯, 不過個別工具都要單獨使用, 如果有一個整合工具, 那就太方便了, 這就是 pipenv, 它把 pip、pyenv 以及另一套虛擬環境管理工具 virtualenv 完美結合在一起, 而且跨平台, 可以讓你實現以單一資料夾為專案, 建立使用特定 Python 版本的虛擬環境, 再也不怕專案之間打架了。
安裝 pipenv 只要使用 pip 即可, 但請記得安裝在你的使用者資料夾下, 避免它安裝的可執行檔因為移除 Python 而被刪除:
安裝完成後, 還要記得將安裝好的可執行檔所在的資料夾加入環境變數 PATH 中, 方便使用:
在 Windows 上可以透過以下指令查詢路徑:
這會找到 site-packages 資料夾的路徑, 剛剛安裝的可執行檔放置在上一層的 Scripts 下, 以剛剛的結果為例, 就要將 C:\Users\meebo\AppData\Roaming\Python\Python312\Scripts
加到 PATH 環境變數中。
在 Linux/macOS 上則可透過以下指令查詢路徑:
安裝 pipenv 會將可執行檔放到這個路徑下的 bin 資料夾, 以剛剛的結果為例, 就要在 shell 的設定檔中將 /home/meebox/.local/bin
加到路徑中。
設定好環境變數後, 只要重新啟動 shell, 就可以使用 pipenv 了。
要建立虛擬環境, 只要先建立專案資料夾, 切換到專案路徑後下達 pipenv install
指令即可。以下我們先使用 pyenv 指定使用 Python 3.12.1 版:
接著建立一個虛擬環境, 以下指令會以 pyenv 以安裝的最新 Python 版本 (3.12.1) 建立虛擬環境:
為了測試結果, 我們先將 Python 切換成不同版本:
接著就可以在這個資料夾內以pipenv run
指令啟用虛擬環境執行程式, 例如:
你可以看到執行的是剛剛建立虛擬環境時使用的 3.12.1, 而不是現在的 3.11.7。如果覺得這樣執行程式有點麻煩, 也可以下達 pipenv shell
開啟啟用虛擬環境的 shell:
我們在這裡安裝 cowsay
套件, 稍後在其他專案資料夾建立虛擬環境時, 就可以看到虛擬環境的效果。
安裝好之後使用 exit
指令離開這個 shell。
你也可以在建立虛擬環境時加入 --python
參數指定 Python 版本, 例如:
這樣就在 test2 資料夾建立了一個同樣是 Python 3.12.1 版本的虛擬環境:
雖然都是 Python 3.12.1, 但因為會建立虛擬環境, 所以和之前的 test1 互相獨立, 你可以確認這個環境中並沒有剛剛安裝的 cowasay 套件:
你可以看到這是一個乾淨的環境, 並沒有安裝任何套件。
如果想要以目前 pyenv 採用的 Python 版本建立虛擬環境, 可以透過 pyenv which python
取得 Python 直譯器的完整路徑, pipenv install
的 --python
參數也可以接受路徑, 因此, 我們可以如下以當前 Python 版本建立虛擬環境:
這樣就可以建立當前使用 Python 版本的虛擬環境, 而不用明確標示版本了。
由於 pipenv 與 pyenv 緊密結合, 所以如果建立虛擬環境時指定的 Python 版本尚未安裝, 它也可以透過 pyenv 自動安裝, 例如:
當 pipenv 發現指定的 Python 3.10.8 尚未安裝時, 就會問我們是否要安裝這個版本。按下 Y 就會開始安裝並在安裝完成後建立虛擬環境, 我們可以確認看看是否會執行 3.10.8 版:
透過這樣的方式, 就可以以資料夾為單位建立專案, 並且以指定的 Python 版本建立虛擬環境, 非常方便。
雖然 pipenv 和 pyenv 是絕配, 不過如果你的系統上有不是透過 pyenv 安裝的 Python, 只要在 PATH 環境變數的路徑中可以找到, 或是直接指定路徑, 也一樣可以使用 pipenv 建立虛擬環境。
例如系統上有透過官網下載安裝的 3.9.6 版:
如果將所在路徑加入 PATH 中:
就可以建立虛擬環境:
你也可以在建立虛擬環境時直接指定 python 執行檔的路徑:
不過我還是建議讓 pipenv 搭配 pyenv 使用會比較簡單。
要在虛擬環境中安裝套件, 可以直接透過 pipenv install
指令, 或者也可以 pipenv shell
啟用虛擬環境開啟 shell 後, 在 shell 中以 pip 指令逕行安裝。以下我們就幫剛剛建立的虛擬環境安裝 coesay 套件:
建立好專案的虛擬環境後, 如果專案資料夾要異動, 都有需要注意的地方。
如果你想要將已經建立的專案資料夾複製到其他地方使用, 只要在複製後重新執行 pipenv install
指令即可, 例如:
這樣就可以複製出一個相同版本的虛擬環境, 而且也會自動安裝原來虛擬環境中的套件:
其實你也可以在複製資料夾後, 直接以 pipenv run
或是 pipenv shell
指令執行, pipenv 會在發現這個專案資料夾還沒有建立虛擬環境時自動建立。
如果是要將專案搬移位置, 基本程序就和複製專案資料夾一樣, 不過由於虛擬環境的資料是儲存在其他位置, 最好在搬移前先移除虛擬環境, 否則搬移到新位置重新建立虛擬環境後, 原來的虛擬環境就變成孤兒, 徒然浪費儲存空間。
例如, 若要將 test4 改名為 test5, 就可以先使用 pipenv --rm
指令刪除虛擬環境之後再搬移, 重新建立虛擬環境:
由於 pipenv 是以資料夾為專案, 所以若是要刪除專案, 其實就是把資料夾移除即可。不過和搬移專案資料夾一樣, 最好在刪除專案資料夾之前先使用 pipenv --rm
移除虛擬環境的資料, 避免佔用儲存空間。
你可能會覺得有點神奇, 移除虛擬環境的資料後, 為什麼可以重新建立一模一樣的虛擬環境?這主要是因為 pipenv 會將相關資訊記錄在資料夾中的 Pipfile 檔:
你可以看到這個檔案中記錄了要使用的 Python 版本以及安裝的套件。當 pipenv 發現這個資料夾還沒有建立虛擬環境時, 就會依據檔案內容建立虛擬環境, 並且安裝所有的套件。
如果想要知道專案對應的虛擬環境儲存在哪裡, 可以下達 pipenv --venv
指令:
你可以看到實際上虛擬環境的資料都是儲存在這裡, 如果你搬移專案或是刪除專案時沒有移除虛擬環境, 而且又安裝了一大堆的套件, 就會佔用非常多的儲存空間。
另外, 要特別提醒的是, 虛擬環境的名稱預設是以專案資料夾的完整路徑編碼而成, 如果你移除或是搬移專案時沒有先移除虛擬環境, 日後若在同一位置建立相同名稱的專案資料夾, 就會沿用殘留的虛擬環境, 造成不必要的問題。舉例來說, 假設剛剛建立的 test5 專案已經結束, 所以我們把資料夾刪除, 同時也把不再需要的 Python 3.10.8 移除:
由於我們沒有移除虛擬環境, 所以如果在同樣位置再次建立 test5 資料夾:
再重新進入資料夾建立虛擬環境:
你可以看到沒有指定版本建立虛擬環境時, 應該會以 pyenv 以安裝的最新版本 3.12.1 為依據建立全新的虛擬環境。但是當你啟用虛擬環境執行時, 會發現它想要執行的是殘留的虛擬環境設定的 3.10.8 版。
即使你指定安裝版本也沒用:
也正因為如此, 才會不斷強調要搬移或是移除專案前, 最好先移除虛擬環境, 這樣既不會佔用空間, 也不會造成意外的結果。