# 虛擬環境
:::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」。

3. 點擊 Venv

4. 選擇你想要的 Python 版本(會列出你電腦上已安裝的版本)。

5. 如果有 requirements.txt,VSCode 會問你要不要一併安裝套件,點「確定」。

6. 右下角畫面顯示建立虛擬環境中,等待一下便完成建立

---
## 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 套件與環境管理工具

[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)