Python虛擬環境實踐

開發每個Python項目時,都推薦創建對應的virtualenv來隔離開發。 這樣可以不受系統Python軟件包的影響,安裝任意包的任意版本,並且最終能通過pip freeze > requirements.txt獲取依賴列表。當然,這個列表通常需要裁剪。

一、安裝virtualenv

使用apt、yum等包管理器安裝的版本老舊,推薦使用pip安裝。

python3.6 -m pip install virtualenv

二、準備virtualenv

每個項目,都需要獨立創建一個(或多個)虛擬環境,隔離開發。

virtualenv -p python3.6 venv
  • -p是顯式指定Python版本,避免使用默認的python。
  • 虛擬環境的常用名,可選擇envvenv.env.venv
root@SS-DTA:/home/nbsprc# ls -alh
total 12K
drwxr-xr-x 3 root root 4.0K May 25 03:03 .
drwxr-xr-x 9 root root 4.0K May 25 02:52 ..
drwxr-xr-x 5 root root 4.0K May 25 03:03 venv

三、激活virtualenv

默認使用的是用戶+系統環境,激活後纔是虛擬環境。

source venv/bin/activate

激活虛擬環境後,可以看到只有三個Python包。 這個環境可以隨意使用,所有安裝都會在./venv/下,不會影響系統環境。 乾淨的環境,也能幫助開發人員確認依賴。

(venv) root@SS-DTA:/home/nbsprc# pip list
Package    Version
---------- -------
pip        19.1.1
setuptools 41.0.1
wheel      0.33.4

在這個虛擬環境中,python就是python3.6,而系統環境的python通常是python2。 在安裝軟件時,直接使用pip,即可安裝到虛擬環境中。 而不像一般狀態下,要麼加sudo提權([brew]或Windows環境下不用),要麼安裝時需要加–user,安裝到用戶目錄下。

四、退出virtualenv

deactivate

退出後,回到用戶+系統環境。

五、虛擬環境的原理

virtualenv是如何創建一個隔離的Python虛擬環境?這個環境有什麼特點?

這個環境的特點:

  • Python版本固定。即使系統的Python升級了,虛擬環境中的仍然不受影響,保留開發狀態。
  • 所有Python軟件包,都只在這個環境生效。一旦退出,則回到用戶+系統的默認環境中。

這兩個特點,由兩個小手段實現。

  • 改變當前Shell的PATH
  • 改變Python運行時的sys.path

改變PATH

root@SS-DTA:/home/nbsprc# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
(venv) root@SS-DTA:/home/nbsprc# echo $PATH
/home/nbsprc/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

顯然,這個activate,爲當前PATH增加了/home/nbsprc/venv/bin這個位置在最前方,因此虛擬環境中的可執行文件擁有最高優先級。 而lib與include,僅僅是bin下面的可執行文件做相對路徑運算來尋找的位置。 所以,改變了PATH,就改變了很多事。

由於優先級最高,所以環境裏的python、pip等,包括後來用pip安裝的可執行文件,都使用的是venv下的。

改變sys.path

root@SS-DTA:/home/nbsprc# python3.6 -m site
sys.path = [
    '/home/nbsprc',
    '/usr/lib/python36.zip',
    '/usr/lib/python3.6',
    '/usr/lib/python3.6/lib-dynload',
    '/usr/local/lib/python3.6/dist-packages',
    '/usr/local/lib/python3.6/dist-packages/setuptools-41.0.1-py3.6.egg',
    '/usr/lib/python3/dist-packages',
]
USER_BASE: '/root/.local' (exists)
USER_SITE: '/root/.local/lib/python3.6/site-packages' (doesn't exist)
ENABLE_USER_SITE: True
(venv) root@SS-DTA:/home/nbsprc# python -m site
sys.path = [
    '/home/nbsprc',
    '/home/nbsprc/venv/lib/python36.zip',
    '/home/nbsprc/venv/lib/python3.6',
    '/home/nbsprc/venv/lib/python3.6/lib-dynload',
    '/usr/lib/python3.6',
    '/home/nbsprc/venv/lib/python3.6/site-packages',
]
USER_BASE: '/root/.local' (exists)
USER_SITE: '/root/.local/lib/python3.6/site-packages' (doesn't exist)
ENABLE_USER_SITE: False

可見,sys.path發生了翻天覆地的變化。 除了當前路徑/root和標準庫/usr/local/lib/python3.6被保留以外,其它位置都換成了venv下的。 這就是爲什麼pip list看不見什麼軟件包的原因,也是環境隔離的最大祕密。

參考:匿蟒-Python中的虛擬環境(Virtualenv)及其工作原理

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章