# 虛擬環境 :::info 本教材以 Windows 環境進行說明 ::: ## 為什麼需要虛擬環境? 當你用 Python 開發不同專案時,每個專案可能需要不同的套件版本,甚至不同的 Python 版本。如果共用同一個 Python 環境,就可能發生「套件衝突」。例如: > 專案 A 需要套件 requests 2.28,而專案 B 需要套件 requests 2.31,在只能安裝一個版本的套件時,可能導致某個專案無法運行。 虛擬環境就像為每個專案打造一個獨立的「小房間」,裡面的 Python 版本和套件只屬於這個專案,不會影響其他專案的程式執行。 ## 虛擬環境的基本概念 虛擬環境能為每個專案提供獨立的 Python 環境,避免套件衝突或版本問題。它的 Python 版本通常取決於 PATH 環境變數中優先找到的 Python 可執行檔。例如: 1. 如果 PATH 是 `D:\python311;D:\python312`,執行 `python --version` 時會優先使用 `D:\python311\python.exe`,因此虛擬環境會基於 Python 3.11 建立。 2. 如果 PATH 是 `D:\python312;D:\python311`,則優先使用 Python 3.12 建立虛擬環境。 :::info 在終端機下達 `where python` 即可得知目前使用的 Python 可執行檔路徑。 ::: 要建立虛擬環境有許多方式,以下介紹這幾種使用方式 1. 使用 Python 內建的 venv(推薦給新手) 2. 使用 virtualenv 套件 3. uv:現代化的 Python 套件與環境管理工具 | 工具 | 優點 | 缺點 | 適用場景 | | -------- | -------- | --- | -------- | | venv | 內建,無需安裝,簡單易用 | 功能較基礎,無法指定 Python 版本 | 初學者、小型專案 | | virtualenv| 靈活,可指定 Python 版本 | 需要額外安裝,配置稍複雜 | 進階使用者、需要特定版本 | | uv | 速度快,功能強大,現代化工作流程 | 學習曲線較陡,需熟悉新工具 | 大型專案、團隊協作、進階開發 | ## 1. 使用 Python 內建的 venv 這是最簡單的方式,因為它是 Python 內建的功能,無需額外安裝。 ```bash # 建立專案目錄並進入 mkdir c:\myprj cd c:\myprj # 建立虛擬環境,命名為 "env"(也可以改成其他名字) python -m venv env # 啟動虛擬環境,你會看到提示符號前多出 (env),表示進入虛擬環境 env\Scripts\activate # 查看目前安裝的套件(剛開始只有少數預設套件) (env) pip list # 更新 pip 版本 (env) python -m pip install --upgrade pip # 確認虛擬環境的 Python 版本是否正確 (env) python --version # 退出虛擬環境 (env) deactivate # 提示符號恢復正常,表示回到全域環境 pip list # 顯示全域的套件 ``` ### 安裝套件 ```bash= (env) pip install requests # 安裝 requests 套件 (env) pip list # 確認 requests 已安裝 ``` ### 記錄專案使用的套件清單 ```bash= (env) pip freeze > requirements.txt ``` 會產生一個 requirements.txt 檔案,記錄所有套件和版本 ### 根據套件清單安裝套件 ```bash= (env) pip install -r requirements.txt ``` 如果換電腦或分享專案,這個指令能快速安裝所有需要的套件。 ### 如何在批次檔中呼叫虛擬環境 #### run.cmd ```bash= @echo off rem 切換工作目錄至批次檔所在目錄 cd /d "%~dp0" rem 如果不在虛擬環境下,則啟動虛擬環境 if not defined _OLD_VIRTUAL_PROMPT ( call env\Scripts\activate ) rem 啟動 flask 執行 main.py flask --debug -A main run -h 0.0.0.0 -p 80 ``` ### 刪除虛擬環境 刪除虛擬環境只需直接刪除虛擬環境目錄即可,假設虛擬環境的名稱為 env,刪除指令如下: ```bash! del /s /q env ``` ### 在 VSCode 建立虛擬環境 如果開發工具是使用 VSCode,也可以嘗試用功能表的方式呼叫 python 以 venv 的方式建立虛擬環境。 **步驟**: 1. 開啟 VSCode,點擊「檔案」 > 「開啟資料夾」,選擇你的專案資料夾(例如 c:\myprj)。 2. 此時不要開啟任何檔案,按下【F1】,輸入 python create,選擇「Python: Create Environment」。 ![image](https://hackmd.io/_uploads/SkUkDKHm1e.png) 3. 點擊 Venv ![image](https://hackmd.io/_uploads/B11QPYS7Jx.png) 4. 選擇你想要的 Python 版本(會列出你電腦上已安裝的版本)。 ![image](https://hackmd.io/_uploads/SJ-vvKHXke.png) 5. 如果有 requirements.txt,VSCode 會問你要不要一併安裝套件,點「確定」。 ![image](https://hackmd.io/_uploads/Byf4dFHX1e.png) 6. 右下角畫面顯示建立虛擬環境中,等待一下便完成建立 ![image](https://hackmd.io/_uploads/S1ttdtrmyg.png) --- ## 2. 使用 virtualenv 套件 virtualenv 支援舊版 Python(例如 Python 2.x),而 venv 僅支援 Python 3.3+。virtualenv 套件,比內建的 venv 更靈活,還可以指定特定的 Python 版本。 ```bash= # 全域安裝 virtualenv pip install virtualenv # 確保 virtualenv 是最新版本 pip install --upgrade virtualenv # 建立虛擬環境 env ## 1. 使用 PATH 環境變數 中優先找到的 python 可執行檔建立 virtualenv env ## 2. 直接指定 python 可執行檔建立 virtualenv -p D:\python312\python.exe env # 啟動虛擬環境,提示符號前加上虛擬環境名稱 env env\Scripts\activate (env) pip list # 退出虛擬環境 (env) deactivate pip list ``` :::warning - 若使用版本管控軟體(如 Git),記得將虛擬環境目錄(例如 env)加入 .gitignore。 - 相較於 venv,virtualenv 建立的虛擬環境在 Lib 目錄中包含較少的預裝函式庫,因此打包成可執行檔(如使用 PyInstaller)時會更輕量。 ::: ### virtualenv 的進階用法 #### 虛擬環境的複製 這對於測試不同套件版本或在多個專案中重用環境很有幫助。 ```bash! virtualenv --clone source_env new_env ``` #### 自訂虛擬環境的提示符號 ```bash! virtualenv --prompt "(myproject) " env ``` #### 允許虛擬環境存取全域 site-packages 適用於需要全域套件的場景 ```bash! virtualenv --system-site-packages env ``` ## 3. uv:現代化的 Python 套件與環境管理工具 ![image](https://hackmd.io/_uploads/H1tjIxVC1x.png) [uv](https://github.com/astral-sh/uv) 是一個用 Rust 編寫的高效能 Python 套件和環境管理工具,旨在取代傳統的 pip、virtualenv 等工具。如果你熟悉 Node.js 的 npm 或 Yarn,會發現 uv 的使用方式有許多相似之處,例如依賴鎖定和快速執行程式。 它的主要特色是: - 速度極快:安裝套件速度比 pip 快 10-100 倍 - 智慧依賴解析:更好地處理套件之間的相依關係 - 一體化管理:同時處理虛擬環境和套件安裝,簡化工作流程 - 向後兼容:支援大多數 pip 指令,方便從傳統工具遷移 uv 是一個強大且現代化的工具,雖然學習曲線稍陡,但學會後能顯著提升開發效率,特別適合需要處理複雜依賴關係的專業開發環境。 ### 安裝 uv Windows 環境下使用 PowerShell 安裝 uv,另外 PowerShell 必須以管理員權限執行,否則無法修改 PATH ```bash= powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" ``` 執行上述 powershell 指令後,會在 `%USERPROFILE%\.local\bin\` 目錄下產生 `uv.exe` 與 `uvx.exe`,並將該路徑加入使用者的 PATH 環境變數中,可下達指令 ``` uv --version # uv -V ``` 若顯示版本號,則代表安裝成功。 因為 uv 目前處於快速發展期,請定期更新 uv 至最新版本 ``` uv self update ``` ### 基礎使用 #### 步驟 1:建立新專案 會在專案中產生 pyproject.toml 檔案,作為專案的設定檔。 ```bash= # 方式 1:建立專案目錄並初始化 uv init myproject # 方式 2:在現有目錄中初始化 mkdir myproject cd myproject uv init . ``` #### 步驟 2:安裝套件(自動建立虛擬環境) ```bash= cd myprj # 建立虛擬環境 .venv (可省略,直接執行安裝套件) uv venv # 安裝一個套件,如果還沒有虛擬環境會自動建立 uv add httpx ``` 當你第一次執行 uv add 時,uv 會: 1. 自動在專案目錄下建立 .venv 虛擬環境 2. 安裝指定的套件 httpx 3. 更新 pyproject.toml 記錄相依套件 #### 步驟 3:執行程式 使用 uv run 會自動在專案的虛擬環境中執行指定的程式。 ```bash= # 執行 Python 檔案 uv run main.py # 查看虛擬環境中安裝了那些套件 uv pip list ``` #### 其它常用指令 ```bash= # 安裝特定版本套件 uv add requests==2.31.0 # 安裝多個套件 uv add requests pandas matplotlib # 升級套件 uv add --upgrade requests # 移除套件 uv remove requests # 檢視已安裝套件 uv pip list ``` ### 管理多個 Python 版本 ```bash= # 顯示可安裝以及已安裝的 Python 版本 uv python list # 顯示 uv 將 Python 安裝在哪個目錄 uv python dir # C:\Users\Administrator\AppData\Roaming\uv\python # 安裝 Python 最新版本 uv python install # 安裝特定的版本 uv python install 3.10 3.11 3.12 # 指定要使用的 Python 版本 uv python pin 3.12 # 移除指定 Python 的版本 uv python uninstall 3.10 # 相依性檢查 uv pip check ``` #### 不同專案使用不同的虛擬環境 當我們的電腦透過 uv 安裝了多個 Python 版本後,該如何設定專案使用特定的 Python 版本呢? ```bash= # 查看系統中可用的 Python 版本 uv python list # 安裝 3.11 與 3.12 二個版本 uv python install 3.11 3.12 # 建立專案與進入專案目錄 md myprj cd myprj # 建立虛擬環境時,指定要用的版本 uv venv --python 3.12 # 初始化 uv init # 建立虛擬環境後再安裝套件 uv add requests # 驗證虛擬環境的 Python 版本 uv run python --version # 執行專案程式 uv run main.py ``` ### 進階使用 #### 手動啟用虛擬環境 雖然大多數情況使用 uv run 就足夠,但有時可能需要手動啟用虛擬環境。 ```bash= # 啟用虛擬環境 .venv\Scripts\activate.bat (.venv) python main.py # 離開虛擬環境 (.venv) deactivate ``` 啟用後,命令提示字元前會出現 (.venv) 提示符號,表示已進入虛擬環境。此方法適合需要長期在虛擬環境中工作的場景,例如除錯測試或執行多個命令。 :::warning 若使用 PowerShell 在 Windows 上啟動虛擬環境(Scripts\activate.bat)時,可能因為 PowerShell 的執行策略限制而失敗,此時需執行以下指令: ```bash! Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned .venv\Scripts\Activate.ps1 ``` ::: #### 刪除虛擬環境 ```bash! uv venv --delete .venv ``` ### 團隊協作:依賴鎖定與環境同步 #### 鎖定依賴(uv lock) 會產生 uv.lock 檔案,精確記錄所有直接和間接相依套件的版本,確保團隊成員可以重現相同的環境。 ```bash= uv lock ``` #### 同步環境(uv sync) uv sync 命令會根據 pyproject.toml 和 uv.lock(如果存在)更新虛擬環境,安裝缺少的套件、移除多餘的套件,取代傳統的 pip install -r requirements.txt 功能,但功能更完整。 ```bash= uv sync ``` #### 協作工作流程 在團隊開發中的標準工作流程: 1. 修改依賴套件:`uv add/remove <package>` 2. 鎖定版本:`uv lock` 3. 提交變更:將 pyproject.toml 和 uv.lock 一起提交到版本控制系統 4. 其他團隊成員只需執行 `uv sync` 就能獲得完全相同的環境 這種方法類似於 npm 的 package.json/package-lock.json 或 Yarn 的 yarn.lock 機制,是現代套件管理的最佳實踐。 ### 其他實用功能 #### 從 requirements.txt 安裝套件 ```bash! uv init uv add -r requirements.txt ``` #### 安裝全域可以使用的工具 使用此方式安裝的工具,會被編譯成 .exe 執行檔放到 `C:\Users\使用者名稱\.local\bin` ```bash! # 安裝 sqlmap uv tool install sqlmap # 檢視目前安裝了哪些工具 uv tool list # 移除 sqlmap uv tool uninstall sqlmap ``` #### 裝開發依賴(僅用於開發環境) 開發依賴會記錄在 pyproject.toml 的 [project.optional-dependencies] 區塊中。 ```bash! uv add --dev pytest black ``` ## 參考網站 - [使用 uv 管理 Python 環境](https://dev.to/codemee/shi-yong-uv-guan-li-python-huan-jing-53hg)