12. 虛擬環境與套件

12.1. 簡介

Python 應用程式通常會用到不在標準函式庫的套件和模組。應用程式有時候會需要某個特定版本的函式庫,因為這個應用程式可能需要某個特殊的臭蟲修正,或是這個應用程式是根據該函式庫特定版本的介面所撰寫。

這意味著不太可能安裝一套 Python 就可以滿足所有應用程式的要求。如果應用程式 A 需要一個特定的模組的 1.0 版,但另外一個應用程式 B 需要 2.0 版,那麼這整個需求不管安裝 1.0 或是 2.0 都會衝突,以致於應用程式無法使用。

解決方案是創建一個虛擬環境 (virtual environment),這是一個獨立的資料夾,並且裡面裝好了特定版本的 Python,以及一系列相關的套件。

不同的應用程式可以使用不同的虛擬環境。以前述中需要被解決的例子中,應用程式 A 能夠擁有它自己的虛擬環境,並且是裝好 1.0 版,然而應用程式 B 則可以是用另外一個有 2.0 版的虛擬環境。要是應用程式 B 需要某個函式庫被升級到 3.0 版,這並不會影響到應用程式 A 的環境。

12.2. 建立虛擬環境

用來建立與管理虛擬環境的模組叫做 venvvenv 通常會安裝你能夠取得的最新版本的 Python。要是你的系統有不同版本的 Python,你可以透過 python3 這個指令選擇特定或是任意版本的 Python。

在建立虛擬環境的時候,在你決定要放該虛擬環境的資料夾之後,以腳本 (script) 執行 venv 模組並且給定資料夾路徑:

python3 -m venv tutorial-env

如果 tutorial-env 不存在的話,這會建立 tutorial-env 資料夾,並且也會在裡面建立一個有 Python 直譯器的複本以及不同的支援檔案的資料夾。

虛擬環境的常用資料夾位置是 .venv。這個名稱通常會使該資料夾在你的 shell 中保持隱藏,因此這樣命名既可以解釋資料夾存在的原因,也不會造成任何困擾。它還能防止與某些工具所支援的 .env 環境變數定義檔案發生衝突。

一旦你建立了一個虛擬環境,你可以啟動它。

在 Windows 系統中,使用:

tutorial-env\Scripts\activate.bat

在 Unix 或 MacOS 系統,使用:

source tutorial-env/bin/activate

(這段程式碼適用於 bash shell。如果你是用 csh 或者 fish shell,應當使用替代的 activate.cshactivate.fish 腳本。)

啟動虛擬環境會改變你的 shell 提示字元來顯示你正在使用的虛擬環境,並且修改環境以讓你在執行 python 的時候可以得到特定的 Python 版本,例如:

$ source ~/envs/tutorial-env/bin/activate
(tutorial-env) $ python
Python 3.5.1 (default, May  6 2016, 10:59:36)
  ...
>>> import sys
>>> sys.path
['', '/usr/local/lib/python35.zip', ...,
'~/envs/tutorial-env/lib/python3.5/site-packages']
>>>

12.3. 用 pip 管理套件

You can install, upgrade, and remove packages using a program called pip. By default pip will install packages from the Python Package Index. You can browse the Python Package Index by going to it in your web browser.

pip 有好幾個子指令:"install"、"uninstall"、"freeze" 等等。(可以參考安裝 Python 模組指南,來取得 pip 的完整說明文件。)

你可以透過指定套件名字來安裝最新版本的套件:

(tutorial-env) $ python -m pip install novas
Collecting novas
  Downloading novas-3.1.1.3.tar.gz (136kB)
Installing collected packages: novas
  Running setup.py install for novas
Successfully installed novas-3.1.1.3

你也可以透過在套件名稱之後接上 == 和版號來指定特定版本:

(tutorial-env) $ python -m pip install requests==2.6.0
Collecting requests==2.6.0
  Using cached requests-2.6.0-py2.py3-none-any.whl
Installing collected packages: requests
Successfully installed requests-2.6.0

要是你重新執行此指令,pip 會知道該版本已經安裝過,然後什麼也不做。你可以提供不同的版本號碼來取得該版本,或是可以執行 pip install --upgrade 來把套件升級到最新的版本:

(tutorial-env) $ python -m pip install --upgrade requests
Collecting requests
Installing collected packages: requests
  Found existing installation: requests 2.6.0
    Uninstalling requests-2.6.0:
      Successfully uninstalled requests-2.6.0
Successfully installed requests-2.7.0

pip uninstall 後面接一個或是多個套件名稱可以從虛擬環境中移除套件。

pip show 可以顯示一個特定套件的資訊:

(tutorial-env) $ pip show requests
---
Metadata-Version: 2.0
Name: requests
Version: 2.7.0
Summary: Python HTTP for Humans.
Home-page: http://python-requests.org
Author: Kenneth Reitz
Author-email: me@kennethreitz.com
License: Apache 2.0
Location: /Users/akuchling/envs/tutorial-env/lib/python3.4/site-packages
Requires:

pip list 會顯示虛擬環境中所有已經安裝的套件:

(tutorial-env) $ pip list
novas (3.1.1.3)
numpy (1.9.2)
pip (7.0.3)
requests (2.7.0)
setuptools (16.0)

pip freeze 可以複製一整個已經安裝的套件清單,但是輸出使用 pip install 可以讀懂的格式。一個常見的慣例是放這整個清單到一個叫做 requirements.txt 的檔案:

(tutorial-env) $ pip freeze > requirements.txt
(tutorial-env) $ cat requirements.txt
novas==3.1.1.3
numpy==1.9.2
requests==2.7.0

requirements.txt 可以提交到版本控制,並且作為釋出應用程式的一部分。使用者可以透過 install -r 安裝對應的的套件:

(tutorial-env) $ python -m pip install -r requirements.txt
Collecting novas==3.1.1.3 (from -r requirements.txt (line 1))
  ...
Collecting numpy==1.9.2 (from -r requirements.txt (line 2))
  ...
Collecting requests==2.7.0 (from -r requirements.txt (line 3))
  ...
Installing collected packages: novas, numpy, requests
  Running setup.py install for novas
Successfully installed novas-3.1.1.3 numpy-1.9.2 requests-2.7.0

pip 還有更多功能。可以參考安裝 Python 模組指南,來取得完整的 pip 說明文件。當你撰寫了一個套件並且想要讓它在 Python Package Index 上可以取得的話,可以參考發布 Python 模組指南。