[Python 虛擬環境] virtualenv, venv, pipenv, pyenv, conda, … 為什麼有這麼多種? 差別在哪

讓你為專案切分與管理環境的工具

Jim

Jim

2022年5月4日 上午 3:00

技術文章

TL;DR

  • 這些都是讓你為專案建立虛擬環境 (Virtual Environment) 的工具;virtualenv, venv, pipenv 用來管理套件 (package, 也稱函式庫 library);pyenv 用來管理 Python 版本;conda 可以同時管理套件跟語言版本
  • 為什麼有這麼多種?歷史沿革、應用場景、個人偏好…等諸多原因
  • 所以我到底要用哪一個?
    • 只需要管理套件版本:venv (Python 內建、上手方便) 或 pipenv (提供進階自動化)
    • 需要同時管理 Python 語言及套件版本:pyenv 搭配上面兩者,或 conda (Anaconda 或 Miniconda)
    • 機器學習或資料科學專案:conda (Anaconda 或 Miniconda)
    • 想用圖形介面管理虛擬環境:Anaconda

什麼是 Python 的虛擬環境 Virtual Environment?

Python 受歡迎的原因之一在於其豐富的套件 (package) 支援。不管你想用 Python 做什麼,大多數情況下都有現成的套件 (函式庫) 可用,只需要簡單的幾行pip install之後就能夠開始開發功能。但是幾個專案過去之後,若把不同專案所需的套件都放在一起,會有難以管理及版本衝突的問題。例如你打算把專案開源或邀請他人一同協作,要告訴別人需要安裝哪些套件,但pip list卻列出了一堆與目前專案無關的套件;或是你想執行別人的專案程式碼,但所需要的套件 (甚至是 Python 版本) 卻是不相容的舊版等。使用 Virtual Environment,就能為每個專案建立獨立的環境 (套件及語言),不僅管理方便,也能確保不同機器上開發環境的一致性。

使用 venv

從 Python 3.3 版之後,venv 就取代了舊有的 virtualenv 及 pyvenv,在 Windows 上也不再需要額外安裝套件,對初學者來說 venv 就很夠用了。

建立虛擬環境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 我機器上的 Python 版本是 3.7.6
C:\Users\Jim> python --version
Python 3.7.6
 
# 在命令列下建立名為 my_project 的虛擬環境
C:\Users\Jim> python -m venv my_project
 
# 在 Windows 下啟動虛擬環境
C:\Users\Jim> my_project\Scripts\activate
(my_project) C:\Users\Jim>
 
# 補充: 在 Mac 或 Linux 下啟動虛擬環境的指令略有不同
# jim@ubuntu:~$ source my_project/bin/activate
# (my_project) jim@ubuntu:~$
 
# 之後就可以用 pip 安裝各種套件了
 
# 離開虛擬環境
(my_project) C:\Users\Jim>deactivate
C:\Users\Jim>

匯出目前環境安裝的套件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 目前環境中的套件列表
(my_project) C:\Users\Jim>pip list
Package            Version
------------------ ---------
certifi            2021.10.8
charset-normalizer 2.0.12
idna               3.3
lxml               4.8.0
pip                19.2.3
requests           2.27.1
setuptools         41.2.0
urllib3            1.26.8
 
# 匯出目前環境裡的套件
(my_project) C:\Users\Jim>pip freeze > requirements.txt

匯入套件到目前環境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 目前環境裡的套件列表
(my_project) C:\Users\Jim>pip list
Package    Version
---------- -------
pip        19.2.3
setuptools 41.2.0
 
# 安裝 requirements.txt 中的套件到目前環境中
(my_project) C:\Users\Jim>pip install -r requirements.txt
...
Successfully installed certifi-2021.10.8 charset-normalizer-2.0.12 idna-3.3 lxml-4.8.0 requests-2.27.1 urllib3-1.26.8
 
# 安裝完畢
(my_project) C:\Users\Jim>pip list
Package            Version
------------------ ---------
certifi            2021.10.8
charset-normalizer 2.0.12
idna               3.3
lxml               4.8.0
pip                19.2.3
requests           2.27.1
setuptools         41.2.0
urllib3            1.26.8

使用 pipenv

從 Python 3.6 版之後,Python 官方推薦使用 pipenv 為虛擬環境的管理工具。使用之前必須先在全域環境安裝 pipenv

1
C:\Users\Jim>pip install pipenv

接著如果想要安裝任何套件,不用先建置虛擬環境,直接切換到專案目錄下 pipenv install 即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
C:\Users\Jim>cd project1
 
# 安裝 requests
C:\Users\Jim\project1>pipenv install requests
Creating a virtualenv for this project...
Pipfile: C:\Users\Jim\project1\Pipfile
...
Successfully created virtual environment!
Virtualenv location: C:\Users\Jim\.virtualenvs\project1-mROZNXzy
Creating a Pipfile for this project...
Installing requests...
...
Installing dependencies from Pipfile.lock (9234af)...
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.

pipenv 會自動幫你建置虛擬環境 (預設會在使用者家目錄的 .virtualenvs 下面,此處是在 C:\Users\Jim\.virtualenvs\project1-mROZNXzy),並且在虛擬環境中安裝套件。如果要在虛擬環境中執行程式,可以直接使用 pipenv run

1
2
3
4
5
6
7
# main.py
# import requests
# response = requests.get('<https://httpbin.org/ip>')
# print('Your IP is {0}'.format(response.json()['origin']))
 
C:\Users\Jim\\project1>pipenv run python main.py
Your IP is xxx.xxx.xxx.xxx

可以看到我們不再需要虛擬環境的建立/進入/離開等操作,且統一使用 pipenv 開頭的指令進行套件及環境管理。

利用 Pipfile 及 Pipfile.lock 重建/轉移環境

使用 pipenv 的專案下會有 Pipfile 及 Pipfile.lock 兩個檔案,裡面包含了專案套件環境的所有資訊。例如我們想再開一個 project2 專案,並重建 project1 專案的環境:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
C:\Users\Jim>mkdir project2
C:\Users\Jim>copy project1\Pipfile* project2
C:\Users\Jim>cd project2
C:\Users\Jim>pipenv install
Creating a virtualenv for this project...
Pipfile: C:\Users\Jim\project2\Pipfile
...
Successfully created virtual environment!
Virtualenv location: C:\Users\Jim\.virtualenvs\project2-urPudTZH
Installing dependencies from Pipfile.lock (444a6d)...
...
# 環境建置完畢,可以執行相同的 Python 程式
C:\Users\Jim\project2>copy ..\project1\main.py .
C:\Users\Jim\project2>pipenv run python main.py
Your IP is xxx.xxx.xxx.xxx

執行 pipenv install 時,會發生以下事情:

  1. 為該專案建立一個新的虛擬環境 (如果還沒有的話),預設放在使用者家目錄的 .virtualenvs 下面
  2. 如果專案下有 Pipfile 檔案,會沿用並安裝檔案內載明的套件到虛擬環境中
  3. 如果專案下沒有 Pipfile 檔案,但有 requirements.txt 檔案,會安裝該檔案內載明的套件,並且建立 Pipfile 檔案
  4. 如果沒有 Pipfile 也沒有 requirements.txt, 直接建立初始化的 Pipfile 檔案

pipenv 也支援把目前環境匯出為傳統的 requirements.txt, 讓舊專案使用

1
2
# 效果等同 pipenv run pip freeze > requirements.txt
C:\Users\Jim\project2>pipenv lock -r

另外,pipenv (Pipfile) 不只可以管理套件,搭配 pyenv 一起使用還可以管理 Python 版本。

Pipfile 和 Pipfile.lock 的差別

Pipfile 檔案中包含了套件基本訊息,且可以區分預設環境及開發環境 (dev-packages)。例如 project1 下面的 Pipfile 內容:

1
2
3
4
5
6
7
8
9
10
11
12
[[source]]
verify_ssl = true
name = "pypi"
 
[packages]
requests = "*"
 
[dev-packages]
 
[requires]
python_version = "3.7"

Pipfile.lock 會包含更精確的套件版本訊息及相依性,達到版本鎖定的功能,以 project 1為例,可以看到 requests 的版本是 2.27.1,另外也包含了所有安裝 requests 之前要安裝的套件 (如 urllib3,可以用 pipenv graph查看)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
"default": {
  ...
  "requests": {
    "hashes": [ ... ],
    "index": "pypi",
    "version": "==2.27.1"
  },
  "urllib3": {
    "hashes": [ ... ],
    "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'",
    "version": "==1.26.8"
},
...

舉例來說,如果專案下面只有 Pipfile, pipenv 在建立安裝環境時會安裝最新版的 requests;但如果有 Pipfile.lock,則會安裝特定的 2.27.1 版

使用 Anaconda

為什麼要使用 Anaconda? 這是專門為機器學習與資料科學專案打造的管理工具 (但一般開發者也可以使用),機器學習專案通常需要安裝很多套件如 OpenCV, TensorFlow 等,有時候在 Windows 機器上不是這麼好安裝,Anaconda 預先解決了此類相容性問題,且安裝時會一併預設安裝許多套件及開發環境 (如 Jupyter Notebook 或 Spyder),也提供 GUI 介面,讓初學者比較好上手。Anaconda 優點:

  • 會一併安裝好機器學習專案所需的套件及環境
  • 可以使用 Anaconda Navigator 的 GUI 介面管理虛擬環境 (包含套件及 Python 版本)
  • conda 套件庫是一個第三方套件庫,裡面有預先編譯好的套件,解決 Windows 機器下安裝機器學習類套件時的相容性問題

Anaconda 缺點:

  • 肥。安裝時間長 (會安裝超過 1000 種套件),且佔用硬碟空間大 (3 GB+),啟動也稍慢
  • conda 只是第三方套件庫,資料科學類以外的套件可能找不到 (在 Navigator 中或 conda install 找不到)。遇到這種情況可以進到虛擬環境中用 pip install 安裝

而 Miniconda 是 Anaconda 的瘦身精簡版,沒有提供 GUI 介面,只預設安裝少數套件,但仍然可以享有使用 conda 套件庫及指令的好處。網路上關於 Anaconda 的教學很多,此處就不再贅述。

在 Visual Studio Code 中指定虛擬環境

在 IDE 例如 VS Code 或 PyCharm 中指定虛擬環境的原則都是一樣的:指向該虛擬環境的 Python 執行檔。如果你是自己創建的虛擬環境,執行檔就在環境目錄的 Scripts 目錄下 (例如 my_project\Scripts\python.exe);pipenv 自動建立的虛擬環境,目錄位置可以使用 –venv 參數查詢

1
2
C:\Users\Jim\project1>pipenv --venv
C:\Users\Jim\.virtualenvs\project1-mROZNXzy

接著只要在 IDE 中設定 Python Interpreter 即可。以 VS Code 來說,會自動尋找 pipenv 或 conda 等工具預設的虛擬環境目錄

文章標籤

# python