跳至內容

虛擬環境

當您在 Python 專案中工作時,您可能應該使用虛擬環境(或類似的機制)來隔離您為每個專案安裝的套件。

資訊

如果您已經了解虛擬環境、如何建立和使用它們,您可以跳過此章節。🤓

提示

虛擬環境環境變數不同。

環境變數是系統中可被程式使用的變數。

虛擬環境是一個包含一些檔案的目錄。

資訊

此頁面將教您如何使用虛擬環境以及它們如何運作。

如果您準備好採用一個為您管理一切的工具(包括安裝 Python),請嘗試 uv

建立專案

首先,為您的專案建立一個目錄。

我通常會在我的家目錄/使用者目錄內建立一個名為 code 的目錄。

然後在其中為每個專案建立一個目錄。

// Go to the home directory
$ cd
// Create a directory for all your code projects
$ mkdir code
// Enter into that code directory
$ cd code
// Create a directory for this project
$ mkdir awesome-project
// Enter into that project directory
$ cd awesome-project

建立虛擬環境

當您第一次開始處理 Python 專案時,請在您的專案內 建立一個虛擬環境。

提示

您只需對每個專案執行一次此操作,而不是每次工作時都執行。

要建立虛擬環境,您可以使用 Python 內建的 venv 模組。

$ python -m venv .venv
該命令的含義
  • python:使用名為 python 的程式
  • -m:以腳本方式呼叫模組,我們接下來會告訴它哪個模組
  • venv:使用通常與 Python 一起安裝的名為 venv 的模組
  • .venv:在新目錄 .venv 中建立虛擬環境

如果您已安裝 uv,則可以使用它來建立虛擬環境。

$ uv venv

提示

預設情況下,uv 會在名為 .venv 的目錄中建立虛擬環境。

但您可以透過傳遞帶有目錄名稱的額外參數來自訂它。

該命令會在名為 .venv 的目錄中建立一個新的虛擬環境。

.venv 或其他名稱

您可以將虛擬環境建立在不同的目錄中,但有一個慣例是將其命名為 .venv

啟動虛擬環境

啟動新的虛擬環境,以便您執行的任何 Python 命令或安裝的套件都使用它。

提示

每次您啟動新的終端機工作階段以處理專案時,都請執行此操作。

$ source .venv/bin/activate
$ .venv\Scripts\Activate.ps1

或者,如果您使用 Bash for Windows(例如 Git Bash

$ source .venv/Scripts/activate

提示

每次您在該環境中安裝新的套件時,請重新啟動該環境。

這樣可以確保,當您使用該套件安裝的終端機程式(CLI時,您使用的是虛擬環境中的程式,而不是全域安裝的其他版本,避免版本衝突。

檢查虛擬環境是否已啟用

檢查虛擬環境是否已啟用(先前的指令是否已成功執行)。

提示

這是選用步驟,但這是個好方法,可以檢查一切是否按預期工作,並且您正在使用預期的虛擬環境。

$ which python

/home/user/code/awesome-project/.venv/bin/python

如果它顯示的 python 執行檔位於專案(此例中為 awesome-project)內的 .venv/bin/python,則表示已成功。🎉

$ Get-Command python

C:\Users\user\code\awesome-project\.venv\Scripts\python

如果它顯示的 python 執行檔位於專案(此例中為 awesome-project)內的 .venv\Scripts\python,則表示已成功。🎉

升級 pip

提示

如果您使用 uv 來安裝套件,則您會使用它而非 pip,因此您不需要升級 pip。 😎

如果您使用 pip(Python 預設安裝)來安裝套件,您應該將其升級到最新版本。

許多安裝套件時發生的奇怪錯誤,只要先升級 pip 就能解決。

提示

通常您會在建立虛擬環境後立即執行一次

確保虛擬環境已啟用(使用上述指令),然後執行

$ python -m pip install --upgrade pip

---> 100%

新增 .gitignore

如果您正在使用Git(您應該使用),請新增一個 .gitignore 檔案,將 .venv 中的所有內容排除在 Git 之外。

提示

如果您使用 uv 建立虛擬環境,它已經幫您完成了,您可以跳過此步驟。 😎

提示

在建立虛擬環境後立即執行一次

$ echo "*" > .venv/.gitignore
該命令的含義
  • echo "*":會在終端機中「印出」文字 *(下一部分會稍微改變這個行為)
  • >> 左側指令輸出到終端機的任何內容,都不會被印出,而是寫入到 > 右側的檔案中。
  • .gitignore:要寫入文字的檔案名稱。

* 對 Git 來說代表「所有東西」。因此,它會忽略 .venv 目錄中的所有內容。

該指令會建立一個內容為以下的 .gitignore 檔案:

*

安裝套件

啟用環境後,您就可以在其中安裝套件。

提示

在安裝或升級專案所需的套件時,執行一次

如果您需要升級版本或新增套件,則需要再次執行此操作

直接安裝套件

如果您趕時間,不想使用檔案來宣告專案的套件需求,您可以直接安裝它們。

提示

將程式所需的套件和版本放在檔案中(例如 requirements.txtpyproject.toml)是一個(非常)好的主意。

$ pip install "fastapi[standard]"

---> 100%

如果您有 uv

$ uv pip install "fastapi[standard]"
---> 100%

requirements.txt 安裝

如果您有 requirements.txt,您現在可以使用它來安裝其中的套件。

$ pip install -r requirements.txt
---> 100%

如果您有 uv

$ uv pip install -r requirements.txt
---> 100%
requirements.txt

包含一些套件的 requirements.txt 可能如下所示:

fastapi[standard]==0.113.0
pydantic==2.8.0

執行您的程式

啟用虛擬環境後,您就可以執行您的程式,它會使用虛擬環境中的 Python 以及您在其中安裝的套件。

$ python main.py

Hello World

設定您的編輯器

您可能會使用編輯器,請確保將其設定為使用您建立的相同虛擬環境(它可能會自動偵測),以便您獲得自動完成和程式碼錯誤提示。

例如:

提示

通常您只需要在建立虛擬環境時執行一次。

停用虛擬環境

完成專案工作後,您可以**停用**虛擬環境。

$ deactivate

這樣,當您執行 python 時,它就不會嘗試從該虛擬環境及其安裝的套件中執行。

準備工作

現在您可以開始進行專案了。

提示

您想知道以上這些是什麼嗎?

請繼續閱讀。 👇🤓

為什麼要使用虛擬環境

要使用 FastAPI,您需要安裝 Python

之後,您需要**安裝** FastAPI 和任何您想使用的其他**套件**。

要安裝套件,您通常會使用 Python 隨附的 pip 命令(或類似的替代方案)。

然而,如果您直接使用 pip,套件將會安裝在您的**全域 Python 環境**(Python 的全域安裝)中。

問題所在

那麼,在全域 Python 環境中安裝套件有什麼問題?

在某些時候,您最終可能會編寫許多依賴**不同套件**的不同程式。而您處理的某些專案將會依賴相同套件的**不同版本**。😱

例如,您可以建立一個名為 philosophers-stone 的專案,該程式依賴另一個名為 harry 的套件,使用版本 1。因此,您需要安裝 harry

flowchart LR
    stone(philosophers-stone) -->|requires| harry-1[harry v1]

然後,在稍後的某個時間點,您建立了另一個名為 prisoner-of-azkaban 的專案,該專案也依賴 harry,但這個專案需要 harry 版本 3

flowchart LR
    azkaban(prisoner-of-azkaban) --> |requires| harry-3[harry v3]

但現在問題是,如果您將套件全域安裝(在全域環境中),而不是在本地**虛擬環境**中,您將不得不選擇要安裝哪個版本的 harry

如果您想執行 philosophers-stone,您需要先安裝 harry 版本 1,例如使用

$ pip install "harry==1"

然後,您的全域 Python 環境中就會安裝 harry 版本 1

flowchart LR
    subgraph global[global env]
        harry-1[harry v1]
    end
    subgraph stone-project[philosophers-stone project]
        stone(philosophers-stone) -->|requires| harry-1
    end

但是,如果您想執行 prisoner-of-azkaban,您需要解除安裝 harry 版本 1 並安裝 harry 版本 3(或者直接安裝版本 3 會自動解除安裝版本 1)。

$ pip install "harry==3"

然後,您的全域 Python 環境中就會安裝 harry 版本 3

如果您再次嘗試執行 philosophers-stone,它有可能**無法運作**,因為它需要 harry 版本 1

flowchart LR
    subgraph global[global env]
        harry-1[<strike>harry v1</strike>]
        style harry-1 fill:#ccc,stroke-dasharray: 5 5
        harry-3[harry v3]
    end
    subgraph stone-project[philosophers-stone project]
        stone(philosophers-stone) -.-x|⛔️| harry-1
    end
    subgraph azkaban-project[prisoner-of-azkaban project]
        azkaban(prisoner-of-azkaban) --> |requires| harry-3
    end

提示

Python 套件中很常見的做法是盡力在**新版本**中**避免重大變更**,但為了安全起見,最好是有意地安裝新版本,並在您可以執行測試以檢查一切正常運作時才安裝。

現在,想像一下,如果你的所有專案都依賴許多其他的套件,那將會非常難以管理。而且你最終可能會在某些專案中執行一些不相容版本的套件,卻不知道為什麼有些東西無法正常運作。

此外,根據你的作業系統(例如 Linux、Windows、macOS),它可能已經預先安裝了 Python。在這種情況下,它可能預裝了一些系統所需的特定版本的套件。如果你在全域 Python 環境中安裝套件,你最終可能會破壞作業系統中的一些程式。

套件安裝在哪裡

當你安裝 Python 時,它會在你的電腦中建立一些包含檔案的目錄。

其中一些目錄負責存放你安裝的所有套件。

當你執行

// Don't run this now, it's just an example 🤓
$ pip install "fastapi[standard]"
---> 100%

它會下載一個包含 FastAPI 程式碼的壓縮檔,通常來自 PyPI

它也會下載 FastAPI 所依賴的其他套件的檔案。

然後它會解壓縮所有這些檔案,並將它們放在你電腦的一個目錄中。

預設情況下,它會將下載並解壓縮的檔案放在 Python 安裝目錄中,也就是**全域環境**。

什麼是虛擬環境

解決在全域環境中安裝所有套件所造成問題的方案是,為你處理的每個專案使用一個**虛擬環境**。

虛擬環境是一個**目錄**,與全域環境非常相似,你可以在其中安裝專案所需的套件。

這樣,每個專案都會有自己的虛擬環境(`.venv` 目錄)和它自己的套件。

flowchart TB
    subgraph stone-project[philosophers-stone project]
        stone(philosophers-stone) --->|requires| harry-1
        subgraph venv1[.venv]
            harry-1[harry v1]
        end
    end
    subgraph azkaban-project[prisoner-of-azkaban project]
        azkaban(prisoner-of-azkaban) --->|requires| harry-3
        subgraph venv2[.venv]
            harry-3[harry v3]
        end
    end
    stone-project ~~~ azkaban-project

啟動虛擬環境的意義是什麼

當你啟動虛擬環境時,例如使用

$ source .venv/bin/activate
$ .venv\Scripts\Activate.ps1

或者,如果您使用 Bash for Windows(例如 Git Bash

$ source .venv/Scripts/activate

該命令會建立或修改一些環境變數,這些變數將可供後續命令使用。

其中一個變數是 `PATH` 變數。

提示

你可以在環境變數章節中了解更多關於 `PATH` 環境變數的資訊。

啟動虛擬環境會將其路徑 `.venv/bin`(在 Linux 和 macOS 上)或 `.venv\Scripts`(在 Windows 上)新增到 `PATH` 環境變數中。

假設在啟動環境之前,`PATH` 變數如下所示

/usr/bin:/bin:/usr/sbin:/sbin

這表示系統會在以下位置搜尋程式

  • /usr/bin
  • /bin
  • /usr/sbin
  • /sbin
C:\Windows\System32

這表示系統會在以下位置搜尋程式

  • C:\Windows\System32

啟動虛擬環境後,`PATH` 變數看起來會像這樣

/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin

這表示系統現在會先在以下位置搜尋程式

/home/user/code/awesome-project/.venv/bin

然後才會在其他目錄中搜尋。

因此,當你在終端機中輸入 `python` 時,系統會在以下位置找到 Python 程式

/home/user/code/awesome-project/.venv/bin/python

並使用該程式。

C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32

這表示系統現在會先在以下位置搜尋程式

C:\Users\user\code\awesome-project\.venv\Scripts

然後才會在其他目錄中搜尋。

因此,當你在終端機中輸入 `python` 時,系統會在以下位置找到 Python 程式

C:\Users\user\code\awesome-project\.venv\Scripts\python

並使用該程式。

一個重要的細節是,它會將虛擬環境路徑放在 `PATH` 變數的**開頭**。系統會**先**找到它,然後再找到任何其他可用的 Python。這樣,當你執行 `python` 時,它會使用**虛擬環境中的** Python,而不是任何其他的 `python`(例如,全域環境中的 `python`)。

啟動虛擬環境還會改變其他一些事情,但這是它所做的最重要的事情之一。

檢查虛擬環境

當您檢查虛擬環境是否處於活動狀態時,例如使用

$ which python

/home/user/code/awesome-project/.venv/bin/python
$ Get-Command python

C:\Users\user\code\awesome-project\.venv\Scripts\python

這表示將使用的 python 程式是虛擬環境中的程式。

您在 Linux 和 macOS 中使用 which,在 Windows PowerShell 中使用 Get-Command

該命令的工作方式是,它會去檢查 PATH 環境變數,依序遍歷每個路徑,尋找名為 python 的程式。一旦找到它,它就會顯示該程式的路徑

最重要的部分是,當您呼叫 python 時,就是會執行的那個「python」。

因此,您可以確認您是否位於正確的虛擬環境中。

提示

很容易啟動一個虛擬環境,取得一個 Python,然後轉到另一個專案

而第二個專案將無法運作,因為您正在使用錯誤的 Python,來自另一個專案的虛擬環境。

能夠檢查正在使用哪個 python 很有用。🤓

為何要停用虛擬環境

例如,您可能正在處理一個名為 philosophers-stone 的專案,啟動該虛擬環境,安裝套件並使用該環境。

然後您想處理另一個專案 prisoner-of-azkaban

您前往該專案

$ cd ~/code/prisoner-of-azkaban

如果您沒有停用 philosophers-stone 的虛擬環境,當您在終端機中執行 python 時,它會嘗試使用 philosophers-stone 中的 Python。

$ cd ~/code/prisoner-of-azkaban

$ python main.py

// Error importing sirius, it's not installed 😱
Traceback (most recent call last):
    File "main.py", line 1, in <module>
        import sirius

但如果您停用該虛擬環境並啟動 prisoner-of-azkaban 的新虛擬環境,那麼當您執行 python 時,它將使用 prisoner-of-azkaban 虛擬環境中的 Python。

$ cd ~/code/prisoner-of-azkaban

// You don't need to be in the old directory to deactivate, you can do it wherever you are, even after going to the other project 😎
$ deactivate

// Activate the virtual environment in prisoner-of-azkaban/.venv 🚀
$ source .venv/bin/activate

// Now when you run python, it will find the package sirius installed in this virtual environment ✨
$ python main.py

I solemnly swear 🐺

替代方案

這是一個簡單的指南,可幫助您入門並教您一切底層是如何運作的。

有許多管理虛擬環境、套件依賴項(需求)和專案的替代方案

當您準備好並想要使用工具來管理整個專案、套件依賴項、虛擬環境等時,我建議您嘗試 uv

uv 可以做很多事情,它可以

  • 為您安裝 Python,包括不同版本
  • 管理專案的虛擬環境
  • 安裝套件
  • 管理專案的套件依賴項和版本
  • 確保您有一組確切的要安裝的套件和版本,包括它們的依賴項,以便您可以確保在正式環境中執行專案與在您的電腦上開發時完全相同,這稱為鎖定
  • 以及許多其他事情

結論

如果您閱讀並理解了所有這些,那麼您現在對虛擬環境的了解比許多開發人員都多得多。🤓

了解這些細節很可能在將來除錯一些看似複雜的問題時派上用場,但您將會知道底層是如何運作的。😎