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 版本(如--version 選項所報告的)。例如使用python3.12 執行命令將安裝 3.12 版本。

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

python-mvenvtutorial-env

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

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

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

在 Windows 系統中,使用:

tutorial-env\Scripts\activate

在 Unix 或 MacOS 系統,使用:

sourcetutorial-env/bin/activate

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

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

$source~/envs/tutorial-env/bin/activate(tutorial-env)$pythonPython3.5.1(default,May62016,10:59:36)...>>>importsys>>>sys.path['','/usr/local/lib/python35.zip',...,'~/envs/tutorial-env/lib/python3.5/site-packages']>>>

要停用虛擬環境,輸入:

deactivate

於終端機中。

12.3.用 pip 管理套件

你可以使用一個叫做pip 的程式來安裝、升級和移除套件。pip 預設會從Python Package Index 安裝套件。你可以透過你的網頁瀏覽器瀏覽 Python Package Index。

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

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

(tutorial-env)$python-mpipinstallnovasCollectingnovasDownloadingnovas-3.1.1.3.tar.gz(136kB)Installingcollectedpackages:novasRunningsetup.pyinstallfornovasSuccessfullyinstallednovas-3.1.1.3

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

(tutorial-env)$python-mpipinstallrequests==2.6.0Collectingrequests==2.6.0Usingcachedrequests-2.6.0-py2.py3-none-any.whlInstallingcollectedpackages:requestsSuccessfullyinstalledrequests-2.6.0

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

(tutorial-env)$python-mpipinstall--upgraderequestsCollectingrequestsInstallingcollectedpackages:requestsFoundexistinginstallation:requests2.6.0Uninstallingrequests-2.6.0:Successfullyuninstalledrequests-2.6.0Successfullyinstalledrequests-2.7.0

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

python-mpipshow 可以顯示一個特定套件的資訊:

(tutorial-env)$python-mpipshowrequests---Metadata-Version:2.0Name:requestsVersion:2.7.0Summary:PythonHTTPforHumans.Home-page:http://python-requests.orgAuthor:KennethReitzAuthor-email:me@kennethreitz.comLicense:Apache2.0Location:/Users/akuchling/envs/tutorial-env/lib/python3.4/site-packagesRequires:

python-mpiplist 會顯示虛擬環境中所有已經安裝的套件:

(tutorial-env)$python-mpiplistnovas(3.1.1.3)numpy(1.9.2)pip(7.0.3)requests(2.7.0)setuptools(16.0)

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

(tutorial-env)$python-mpipfreeze>requirements.txt(tutorial-env)$catrequirements.txtnovas==3.1.1.3numpy==1.9.2requests==2.7.0

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

(tutorial-env)$python-mpipinstall-rrequirements.txtCollectingnovas==3.1.1.3(from-rrequirements.txt(line1))...Collectingnumpy==1.9.2(from-rrequirements.txt(line2))...Collectingrequests==2.7.0(from-rrequirements.txt(line3))...Installingcollectedpackages:novas,numpy,requestsRunningsetup.pyinstallfornovasSuccessfullyinstallednovas-3.1.1.3numpy-1.9.2requests-2.7.0

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