2025年12月10日 星期三

關於 Python 的 venv 虛擬環境用法

這陣子我手上的樹莓派陸續升版為最新的 Trixie OS, 不允許直接在系統 Python 環境用 pip 安裝第三方套件 (自上一版 Bookworm 開始遵循 PEP 668 規範), 必須建立虛擬環境後在裡面安裝, 所以之後會很常使用 venv 指令. 

最常用的三個 venv 指令如下 (myvenv 是自訂的虛擬環境資料夾名稱) :
  • 建立虛擬環境 : python -m venv myvenv 
  • 進入虛擬環境 : surce myvenv/bin/activate
  • 退出虛擬環境 : deactivate
今天在 "Raspberry Pi 5 + AI創新實踐 : 電腦視覺與人工智慧應用指南" 這本書最後一章看到它在 python -m venv 指令後面使用了我沒看過的 --system-site-packages 參數, 詢問 Gemini 才知道這是為了在虛擬環境中使用系統 Python 中已經安裝的套件 (例如某些大型或難以編譯的套件如 NumPy 或特定的資料庫驅動等), 使用此參數可在虛擬環境中也能使用它們而毋須重新安裝. 但若在虛擬環境中安裝了與系統同名的套件, 則虛擬環境中的版本會優先使用.

如果建立虛擬環境時使用了 --system-site-packages 參數, 則在此虛擬環境下輸入 pip list 命令會輸出兩類套件混在一起顯示 : 
  • 虛擬環境內用 pip install 手動安裝的套件
  • 系統 Python 的所有套件
如果要查看虛擬環境下安裝的套件, 可以用 pip list --local 指令. 

用 --system-site-packages 建立的虛擬環境在用 pip freeze > requirements.txt 指令進行打包或依賴管理時會有不純淨和混亂的問題, pip freeze 只會列出在虛擬環境中手動安裝的套件, 不會將透過 --system-site-packages 繼承的系統級套件包含在 requirements.txt 中, 當將此專案部署到另一個環境 (例如新的伺服器或同事的電腦) 並嘗試使用 pip install -r requirements.txt 安裝依賴時, 專案會缺少所有必要的系統套件而無法運行, 這也是為什麼在絕大多數的專案中並不建議使用這個參數的原因. 

結論 : 不要用 --system-site-packages 參數建立虛擬環境, 這種虛擬環境不純淨與不可移植, 專案無法保證在其他地方運行結果一致. 

venv 的可用參數整理如下表 : 


參數 說明 範例用途
--clear 如果指定的環境目錄已經存在,則在創建新環境之前會**刪除**現有目錄的內容。 當您想徹底重建一個現有的虛擬環境時使用。
--upgrade-deps 確保環境中的基礎依賴,如 **pip**、**setuptools** 和 **wheel**,被升級到最新的版本。 推薦使用,以確保您使用最新的套件管理工具。
-h, --help 顯示 venv 模組的說明訊息和所有可用參數。 用於查找完整的參數列表。
--copies 強制使用 **複製** 而不是符號連結來安裝環境中的檔案。 在某些檔案系統或作業系統上,符號連結可能會有問題時使用。
--system-site-packages 允許虛擬環境訪問系統安裝的套件。 在需要共用大型系統套件時使用。
--symlinks (預設行為)盡可能使用**符號連結**來安裝環境中的檔案,以節省空間。 如果您使用了 --copies,可以用此選項切換回預設行為。
--prompt <PROMPT> 為虛擬環境指定一個**不同的前綴**,該前綴會顯示在終端機提示符號中,而不是使用目錄名稱。 讓您更容易識別當前激活的是哪個環境,例如 --prompt my-project-dev


如果要在建立虛擬環境時 pip 為最新版, 可以加 --upgrade-deps 參數 :

python -m venv --upgrade-deps myvenv 

例如 :

pi@pi3aplus:~ $ python -m venv streamlit_venv  
pi@pi3aplus:~ $ cd streamlit_venv   
pi@pi3aplus:~/streamlit_venv $ ls -ls   
總用量 16
4 drwxrwxr-x 2 pi pi 4096 12月 10 14:47 bin
4 drwxrwxr-x 3 pi pi 4096 12月 10 14:46 include
4 drwxrwxr-x 3 pi pi 4096 12月 10 14:46 lib
0 lrwxrwxrwx 1 pi pi    3 12月 10 14:46 lib64 -> lib
4 -rw-rw-r-- 1 pi pi  161 12月 10 14:46 pyvenv.cfg

啟動與退出虛擬環境的 activate/deactivate 等指令都放在 bin 底下. 

pi@pi3aplus:~ $ source ~/streamlit_venv/bin/activate    
(streamlit_venv) pi@pi3aplus:~ $ pip list   
Package Version
------- -------
pip     25.1.1
(streamlit_venv) pi@pi3aplus:~ $

可見純淨的虛擬環境剛建立時只有 pip 一個套件而已. 

沒有留言 :