什麼是 Python virtualenv

什麼是Kubernetes – 實際應用 這篇文章中,我們提到了如果要在本地端運行一個程式碼,我們可以將所有需要用到的 package 都安裝在自己的電腦上,或是也可以使用 virtualenv。

這篇我們就要來介紹到底什麼是 virtualenv,為什麼需要用他,也會帶大家一步一步來安裝並且試跑幾個範例!

什麼是 virtualenv

virtualenv 中文就叫做虛擬環境。簡單來說,這個虛擬環境讓你可以在同一台電腦上建立好幾個不同的 python 環境

好啦那重要的問題來了,我們為什麼會需要在同一台電腦上有好幾個不同的 python 環境呢?你可以試想一下,今天假如你有三四個 python 專案正在進行,而且這幾個專案所需要用到的 package 都不一樣,所需要用到的 python 版本也不一樣。

一種解決辦法當然是當你在做 A 專案的時候下載所需要用的 package 以及 python 版本,做 B 專案的時候再下載其他的 package 和所需要的 python 版本。這當然是一種辦法,但我想不用我說你們也知道,這非常花時間,肯定也不會想要有人這麼做!

所以今天這個 virtualenv 就是來幫助我們解決這件事的!一台電腦上我們可以建立不同的 python 環境。在 A 環境上做 A 專案,在 B 環境上做 B 專案等等,這幾個環境互相獨立不受彼此干擾,如果想要切換環境也非常方便!

下載 virtualenv

下載 virtualenv 的步驟非常簡單!一行指令就可以搞定!

$ sudo pip3 install virtualenv

安裝完後,我們可以檢查一下是否安裝成功

$ virtualenv --version

如何使用

下載完成後,我們就可以利用 virtualenv 來建立獨立的 python 環境啦!

我們可以利用這個指令來建立一個 python 環境:

$ virtualenv venv

執行完後,我們會看到多了一個叫做 venv 的檔案夾。接著我們執行這個指令來激活剛建立的環境:

$ source venv/bin/activate

執行完後,我們應該可以看到我們的終端機前面多了一個這樣的符號 (venv),這樣就代表我們在這個獨立的還境理面啦!

我們可以在這個獨立環境下載我們所需要的套件以及所需要的版本,在這裡下載的套件會完全與本機的套件隔離開來,達到 virtualenv 的目的!

你也可以在虛擬環境中執行 pip3 list 這個指令,和在進入虛擬環境前比較,看看有沒有發現什麼區別。

最後如果我們想要跳出這個虛擬環境,直接執行這個指令就可以了:

$ deactivate

最後當我們不再需要這個環境,我們直接刪除這個 venv 的資料夾就可以了,是不是非常方便!

運作原理

講到這邊基本上就講完 virtualenv 該如何使用啦!接下來我們來講講他的運作原理,理解一下他是怎麼做到可以建立各個獨立的 python 環境的。

如果對接下來沒興趣的就可以不用往下看啦~

virtualenv 透過對你電腦上的兩個東西進行修改已達到目的:

  1. $PATH
  2. sys.path

我們先來看 $PATH 是什麼?

$PATH

在 Linux 或 Unix 的操作系统中,$PATH 是一個環境變數,它的組成是一個由冒號分隔開的目錄列表,系統應該在這些目錄列表中查找可以執行的文件。也就是說,當我們在終端機輸入命令時,電腦會在 $PATH 指定的目錄中按照他們的先後顺序搜尋相對應的可執行文件。

舉個例子來說,我們可以透過這個指令將 $PATH 印出來

$ echo $PATH

我們應該會看到類似以下的輸出

/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

這代表如果我們執行 python example.py 這個指令時,我們的電腦會從 $PATH 中的第一個目錄,也就是 /usr/local/bin,查看有沒有一個執行檔叫做 python,如果有的話我們就利用那個執行檔。如果沒有的話,就會忘下一個目錄尋找,也就是 /usr/local/sbin

我們來看看在剛剛創建的虛擬環境 venv 中這個環境參數會長怎麼樣

/root/venv/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

有沒有發現結果不一樣了!這代表當我們執行 python example.py 時,電腦會先去 venv 中尋找 python 這個執行檔,而不是在我們原本電腦上的 python!

sys.path

sys.path 又是什麼呢?sys.path 是 Python 中的一個列表,代表套件的搜索路徑。當 Python 在導入套件時,它會在 sys.path 中列出的目錄中尋找套件所需要的原始程式碼或已經編譯過可執行的檔案。

我們可以執行這個指令來查看當前的 sys.path

$ python3 -m site

你可以看到類似以下的輸出

sys.path = [
    '/root',
    '/usr/local/lib/python39.zip',
    '/usr/local/lib/python3.9',
    '/usr/local/lib/python3.9/lib-dynload',
    '/usr/local/lib/python3.9/site-packages',
]
USER_BASE: '/root/.local' (doesn't exist)
USER_SITE: '/root/.local/lib/python3.9/site-packages' (doesn't exist)
ENABLE_USER_SITE: True

我們可以看到,目前 Python 會在 /usr/local/lib 裡面尋找所需要的套件。

接著我們到剛剛建立的 venv 裡面,再執行一次指令,我們會看到類似這樣的結果

sys.path = [
    '/root',
    '/root/venv/lib/python39.zip',
    '/root/venv/lib/python3.9',
    '/root/venv/lib/python3.9/lib-dynload',
    '/usr/local/lib/python3.9',
    '/root/venv/lib/python3.9/site-packages',
]
USER_BASE: '/root/.local' (doesn't exist)
USER_SITE: '/root/.local/lib/python3.9/site-packages' (doesn't exist)
ENABLE_USER_SITE: False

我們可以發現,現在 Python 會從不同的地方找套件了!

透過改變這兩個變數,Python 就可以做到建立無數不同且互相獨立的開發環境!是不是很神奇又出乎意料的簡單呢!

結語

到這裡我們就徹底介紹完 Python virtualenv 啦!是不是很簡單又很實用呢!

總之,這個工具的終極目標就是要讓開發者可以根據不同的專案建立相對應的獨立開發環境,我們可以在各自的開發環境安裝所需要的套件以及特定的版本,並且這些環境彼此互不相關而且也不會影響到本機上的設定。讓開發流程更簡單!