快轉到主要內容
  1. 教學文章/

Python virtual environments 大比拼:venv vs conda vs uv 怎麼選?

·8 分鐘· loading · loading · ·
Python Venv Conda Uv Virtual Environments Packaging
每日拍拍
作者
每日拍拍
科學家 X 科技宅宅
目錄
Python 學習 - 本文屬於一個選集。
§ 41: 本文

featured

一、前言
#

嗨,我是拍拍君 🐍

只要你開始認真寫 Python,遲早都會遇到同一個問題:虛擬環境到底該用哪一套? 有人說 venv 就夠了,因為它是標準庫內建;有人說資料科學就是 conda 的天下;也有人這兩年全面倒向 uv,因為它真的快得很誇張。

問題是,這三個工具都能建立環境、安裝套件、隔離依賴,那到底差在哪裡?答案是,它們解的其實不是完全同一題。

  • venv 重點是最基本、最標準的 Python 環境隔離
  • conda 重點是連 Python 以外的二進位依賴也一起管
  • uv 重點是現代 Python 工作流整合,加上超快速度

今天這篇,拍拍君會用實戰角度把三者拆開比較,告訴你它們各自擅長什麼、同一個專案用三種工具會長什麼樣子,以及你現在的專案到底該選誰。

如果你之前看過 Python uv:超快 Python 套件管理工具Python Packaging:從 pyproject.toml 到發佈 PyPI 全攻略,今天這篇可以把環境管理這一塊補完整。

二、先搞懂:虛擬環境到底在隔離什麼?
#

虛擬環境不是很重的 sandbox,也不是完整的容器。它最主要做的事情很簡單:讓每個專案有自己獨立的 Python 執行檔與套件安裝位置。

這件事為什麼重要?因為不同專案常常需要不同版本的依賴。專案 A 可能還停在 fastapi==0.95pydantic==1.10,專案 B 卻已經升級到 fastapi==0.111pydantic==2.7。如果你把它們都裝在同一個全域 Python,早晚會撞車。

三個工具的定位,一張表先看懂
#

工具 核心定位 管 Python 版本 管非 Python 依賴 速度體感 最常見場景
venv 內建、基礎、最純粹的環境隔離 普通 純 Python、小專案、教學
conda 跨語言環境與二進位依賴管理 中等 ML、資料科學、科學計算
uv 高速現代 Python 工具鏈 幾乎不碰 非常快 新專案、Web、CLI、自動化

你可以先把它們想成三種不同的工具哲學:venv 是最小可用解,conda 是完整環境發行系統,uv 是現代 Python 開發者工具箱。

三、venv:標準庫內建的基本盤
#

如果你的需求是「我只想讓這個專案有自己的套件環境」,那 venv 幾乎永遠不會太離譜。它從 Python 3.3 起就是標準庫的一部分,所以只要你有 Python,多半就已經有 venv 可以用。

基本建立方式
#

python3 -m venv .venv

這會在專案根目錄建立一個 .venv/,裡面包含專案專用的 pythonpip 與 site-packages。

啟用方式如下。

macOS / Linux:

source .venv/bin/activate

Windows PowerShell:

.venv\Scripts\Activate.ps1

啟用之後,你在這個 shell 裡輸入的 pythonpip,就會指向專案自己的環境。

安裝套件與匯出依賴
#

python -m pip install fastapi uvicorn ruff
python -m pip freeze > requirements.txt

拍拍君會建議優先用 python -m pip,而不是直接打 pip。原因很簡單,你可以很明確知道現在操作的是哪個 Python。這在機器上有多套 Python 時特別重要。

venv 的優點
#

  1. 幾乎零額外成本,不用再裝新工具。
  2. 心智模型很乾淨,它就是建立隔離環境。
  3. 官方文件相容性最好,你看到的大多數教學都能直接套用。

venv 的限制
#

  1. 不管理 Python 版本本身,它使用的是你機器上已經存在的 Python。
  2. 不處理非 Python 原生依賴,像 ffmpeg、CUDA、openssl 這類東西它不管。
  3. 傳統 pip + requirements.txt 在大型專案不夠優雅,尤其當你開始在意 lockfile、依賴分組與重現性時。

什麼情況適合 venv?
#

venv 很適合這些場景:純 Python API 或 CLI、教學範例 repo、小型 side project、短期腳本、公司環境限制多不方便裝新工具。說白了,如果你只是要一個穩穩能跑的隔離環境,venv 其實非常夠用。

四、conda:資料科學與二進位依賴的老將
#

conda 最有價值的地方,不是它「也能建立虛擬環境」,而是它能把很多 Python 以外的依賴 也一起納入環境管理。這在資料科學、機器學習、科學計算領域非常重要。

conda 在解什麼問題?
#

假設你今天要建立一個 ML 專案,需求包含 Python 3.11、numpypandaspytorch,可能還有 CUDA 或其他底層庫。這時候痛點常常不是 pip install 打不打得出來,而是:wheel 有沒有對應平台、底層共享庫版本會不會衝突、這個套件到底需不需要編譯。

conda 的強項,就是把這些二進位依賴當成一等公民看待。

建立 conda 環境
#

conda create -n chatptt-ml python=3.11
conda activate chatptt-ml
conda install numpy pandas jupyter

如果你主要靠社群套件,通常可以優先考慮 conda-forge

conda install -c conda-forge numpy pandas jupyter

conda 可以處理非 Python 套件
#

例如:

conda install -c conda-forge ffmpeg

這一點就是 condavenvuv 的最大分水嶺。很多時候不是比較方便而已,而是終於不用手動解系統依賴地獄。

用 environment.yml 描述環境
#

name: chatptt-ml
channels:
  - conda-forge
dependencies:
  - python=3.11
  - numpy
  - pandas
  - jupyterlab
  - pytorch
  - pip
  - pip:
      - fastapi
      - wandb

建立與更新:

conda env create -f environment.yml
conda env update -f environment.yml --prune

conda 的優點
#

  1. 非 Python 依賴處理能力強,對 ML、資料科學、影像處理、多媒體流程都很關鍵。
  2. Python 版本管理整合自然,建立環境時就能直接指定。
  3. 團隊分享環境描述方便,對研究或實驗型團隊通常很夠用。

conda 的缺點
#

  1. 速度通常不算快,solver 在解依賴時有時候真的慢。
  2. 和官方 Python 工作流有一點平行宇宙感,新手在兩套世界間切換時偶爾會迷路。
  3. conda / pip 混裝需要節制,拍拍君通常建議核心二進位依賴先 conda,再用 pip 補純 Python 套件。

什麼情況適合 conda?
#

如果你的日常是 Notebook-heavy 的資料分析、PyTorch / JAX / 科學計算、需要 CUDA 或大型原生依賴,或團隊既有流程已經建在 conda 上,那 conda 依然很有戰力。這類情境下,離開 conda 不一定比較進步,只是比較折騰而已。

五、uv:新世代高速 Python 工具鏈
#

接下來講這兩年超紅的 uv。如果要用一句話形容它,我會說:它把很多 Python 開發者平常分散在不同工具上做的事,整合成一套速度超快的工作流。

而且它不是 benchmark 漂亮而已,是真的第一次用就會感覺到「欸,怎麼這麼快」。

安裝 uv
#

Homebrew:

brew install uv

官方安裝腳本:

curl -LsSf https://astral.sh/uv/install.sh | sh

建立專案
#

uv init chatptt-api
cd chatptt-api
uv add fastapi uvicorn
uv add --dev pytest ruff
uv sync
uv run python main.py
uv run pytest
uv run ruff check .

如果你只把 uv 當成超快版 venv + pip,就已經很划算了。但它其實還往前多做了幾步。

uv 的強項
#

  1. 速度非常快,建立環境、解依賴、安裝套件都很有感。
  2. pyproject.toml 為中心,很符合現代 Python 專案的寫法。
  3. Lockfile 與同步工作流友善,對團隊協作和 CI 很加分。
  4. 工具執行方便,像 uvx ruff check .uv run --with httpx python script.py 都很順手。

例如一個典型設定會長這樣:

[project]
name = "chatptt-api"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
  "fastapi>=0.111",
  "uvicorn>=0.30",
]

[dependency-groups]
dev = [
  "pytest>=8.0",
  "ruff>=0.4",
]

uv 也能管理 Python 版本
#

uv python install 3.11
uv python pin 3.11
uv venv

這讓它不只是一個安裝器,而是更完整的 Python 開發入口。

uv 的限制
#

  1. 主要還是 Python 世界內的工具,如果你的核心問題是 CUDA、系統共享庫、跨語言二進位套件,那 uv 不是來解這些的。
  2. 舊專案不一定適合立刻硬搬,因為文件、CI、部署腳本不一定同步跟上。
  3. 新工具代表團隊需要共同學習,雖然指令不難,但還是有適應成本。

什麼情況適合 uv?
#

拍拍君最推薦 uv 的場景通常是:新開的 Python 專案、Web API、CLI 工具、自動化腳本與內部工具,以及很在意安裝速度與重現性的團隊。如果專案核心就是 Python,而不是一堆外部原生依賴,uv 幾乎都值得你認真試一次。

六、同一個專案,三種工作流長什麼樣?
#

來看一個具體例子。假設我們要做一個叫 chatptt-service 的 FastAPI 專案,需求如下:

  • Python 3.11+
  • fastapi
  • uvicorn
  • 測試用 pytest
  • 靜態檢查用 ruff

A. 用 venv + pip
#

python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install fastapi uvicorn pytest ruff
python -m pip freeze > requirements.txt
uvicorn app.main:app --reload
pytest

這套很適合教學、小專案、或任何你只想快速把專案獨立起來的情境。

B. 用 conda + environment.yml
#

conda create -n chatptt-service python=3.11
conda activate chatptt-service
conda install -c conda-forge fastapi uvicorn pytest ruff

搭配這個描述檔:

name: chatptt-service
channels:
  - conda-forge
dependencies:
  - python=3.11
  - fastapi
  - uvicorn
  - pytest
  - ruff

重建方式:

conda env create -f environment.yml

如果這個專案日後還要接上更多原生依賴,這條路會比較穩。

C. 用 uv + pyproject.toml
#

uv init chatptt-service
cd chatptt-service
uv add fastapi uvicorn
uv add --dev pytest ruff
uv sync
uv run uvicorn app.main:app --reload
uv run pytest
uv run ruff check .

如果你想固定 Python 版本:

uv python install 3.11
uv python pin 3.11

這套 workflow 對新專案特別流暢,因為依賴、工具、執行與同步幾乎是一體的。

一句話總結三種工作流
#

  • venv 最簡單
  • conda 最能處理複雜依賴
  • uv 最像現代 Python 開發者想要的體驗

七、拍拍君的選擇建議
#

如果是拍腦袋給建議,拍拍君會這樣分:

  • 教學、練習、簡單腳本,選 venv
  • 資料科學、Notebook、PyTorch、原生依賴很多,選 conda
  • 新專案、Web、CLI、內部工具,大概率選 uv

如果今天是我自己開新專案,而且核心就是 Python,我大多會直接從 uv 起手。速度、乾淨度、與 pyproject.toml 的整合都很加分。

但如果一個專案已經穩定跑了兩三年,團隊熟悉 venv + requirements.txt,CI 也都圍繞這套,那就不要只是因為新工具很潮就強推遷移。穩定,比潮更重要。

八、常見迷思與踩坑提醒
#

迷思 1:用了 conda 就不能碰 pip
#

不是不能,而是要有節奏。比較安全的做法是先 conda、後 pip,而且盡量不要讓兩者去搶同一批核心套件的版本主導權。

迷思 2:uv 會完全取代 conda
#

至少現在還不能這樣講。它們解的問題不同。純 Python 專案,uv 常常更舒服;重型 ML 或科學計算環境,conda 依然很難被完全替代。

迷思 3:venv 太老,所以不值得學
#

完全相反。venv 是 Python 生態的基礎知識。就算你最後主力使用 uv,也應該知道 venv 在做什麼。

迷思 4:每個專案都該用同一套工具
#

不一定。成熟工程師比較少追求宇宙唯一正解,而是會看專案性質、團隊熟悉度、CI 流程與維護成本。

九、如果你今天才開始,我會怎麼建議?
#

拍拍君會給一條很務實的學習路線。

第一步,先學會 venv,至少把下面三行變成本能:

python3 -m venv .venv
source .venv/bin/activate
python -m pip install requests

第二步,做新專案時學 uv。當你開始碰 Web API、CLI、pyproject.toml、CI 重現性,uv 很值得投資。 第三步,進資料科學或 ML workflow 時補 conda。等你真的碰到大型原生依賴、GPU、跨平台二進位套件時,你自然會知道為什麼 conda 還活得這麼好。

結語
#

venvcondauv 不是彼此的完全上下位替代關係,它們比較像三把不同尺寸的工具刀。

  • venv 是最標準、最穩的基本款
  • conda 是擅長處理複雜依賴的大工具箱
  • uv 是速度飛快、體驗現代的新選手 如果你只想記一句話,拍拍君的版本是:純 Python、小到中型專案,先考慮 venvuv;資料科學、ML、原生依賴重,優先考慮 conda;新專案又想要好體驗,我最推薦試試 uv

最後提醒一句,不要把環境工具當成身份認同。你不是 venv 派,也不是 conda 派,更不是 uv 派,你只是想把專案穩穩跑起來的 Python 工程師而已 😌

延伸閱讀
#

Python 學習 - 本文屬於一個選集。
§ 41: 本文

相關文章

Python Packaging:從 pyproject.toml 到發佈 PyPI 全攻略
·7 分鐘· loading · loading
Python Packaging Pyproject.toml Pypi Pip Uv Setuptools
超快速 Python 套件管理:uv 完全教學
·6 分鐘· loading · loading
Python Uv Package Manager Rust
Python ABC + Protocol:介面設計與 Structural Subtyping
·8 分鐘· loading · loading
Python Abc Protocol Typing Interface Oop
Python Generators/Yield 完全攻略:惰性運算的藝術
·7 分鐘· loading · loading
Python Generator Yield Lazy Evaluation Iterator
Python click:比 argparse 更優雅的 CLI 框架
·10 分鐘· loading · loading
Python Click Cli 命令列 開發工具
Python pytest:fixture + parametrize + mock 完整指南
·8 分鐘· loading · loading
Python Pytest Testing Fixture Mock Parametrize TDD