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. 建立虛擬環境
==================

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

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

   python -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.csh" 與 "activate.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 模組指南。
