Python 虛擬環境工作原理解析
Python 的虛擬環境用來創建一個相對獨立的執行環境,尤其是一些依賴的三方包,最常見的如不同項目依賴同一個但是不同版本的三方包,而且,在虛擬環境中的安裝包不會影響到系統的安裝包。
不過,其具體的工作原理是怎樣的,這裡詳細介紹。
簡介
幾乎每個語言都包含自己的包管理工具,這是一個非常復雜的話題,而不同語言選擇的實現又略有區別,都會做一些選擇和取舍。而 Python 的包管理解決方案很多,例如 pip、virtualenv、pyenv 等等。
不過 Python 語言本身的機制決定瞭其原理一樣。
使用
比較常用的是 virtualenv 工具,可以參考 Guide to Python 中的詳細介紹,另外,Python3 也提供瞭自己的虛擬環境創建模塊,在創建完成後基本都是通過一個腳本啟用獨立環境。
例如,如下是使用 virtualenv 以及 venv 的虛擬環境創建過程。
$ mkdir /tmp/project && cd /tmp/project $ virtualenv --no-site-packages foobar $ python3 -m venv foobar
然後,就可以通過 source foobar/bin/activate
命令激活新環境。
激活腳本
所謂的獨立環境,無非就是解決兩個問題:A) 執行 Python 解析器所使用的版本;B) 使用獨立的包。其中前者,在 Linux 主要是通過 PATH
環境變量設置,在 activate
腳本中有如下的內容。
VIRTUAL_ENV="/tmp/project/foobar" export VIRTUAL_ENV _OLD_VIRTUAL_PATH="$PATH" PATH="$VIRTUAL_ENV/bin:$PATH" export PATH
也就是將創建的目錄添加到 PATH
環境變量最開始,那麼就會優先查找該路徑,這樣就解決瞭 python 解析器獨立的問題。
工作原理
如果要使用獨立的包,那麼關鍵就是如何在通過 import
導入時查找到所需的包。
包的查找順序可以查看Python 模塊簡介 中的介紹,簡單來說,就是先查看是否是內置模塊,然後再從 sys.path
列表指定的地址中搜索。所以,這裡的關鍵就是 sys.path
列表的生成。
關於 sys.prefix
在 Python 啟動的時候,會先加載一個強依賴的 os.py
包,而查找這個包是根據解析器的當前路徑,以及固定的查找規則來實現的。
簡單來說,就是在當前路徑加上 lib/python${VERSION}/os.py
逐層向上查找,註意,如果是 64 位的操作系統,那麼會使用 lib64
替換掉之前的 lib
路徑。
例如,默認的 Python3 的解析器路徑為 /usr/bin/python3.6
,那麼基礎路徑是 /usr/bin/
,所以,其查找順序為。
/usr/bin/lib64/python3.6/os.py /usr/lib64/python3.6/os.py /lib64/python3.6/os.py
隻要在任意路徑上找到 os.py
包,那麼就會退出查找,並設置好 sys.prefix
變量,詳細可以通過 strace python
查看,會有如下的搜索路徑。
stat("/usr/bin/Modules/Setup", 0x7fffb7146300) = -1 ENOENT (No such file or directory) stat("/usr/bin/lib64/python2.7/os.py", 0x7fffb71462f0) = -1 ENOENT (No such file or directory) stat("/usr/bin/lib64/python2.7/os.pyc", 0x7fffb71462f0) = -1 ENOENT (No such file or directory) stat("/usr/lib64/python2.7/os.py", {st_mode=S_IFREG|0644, st_size=25910, ...}) = 0
在查找到 os.py
之後,會將該路徑設置為 sys.prefix
變量,然後解析器就會到 ${sys.prefix}/lib/python${VERSION}
目錄下查找包。
總結
那麼其工作原理就是,將 python 解析器保存在 ${VENV_PATH}/bin/python
,然後創建 ${VENV_PATH}/lib/python${VERSION}
目錄,並將相關的文件復制到該目錄下,可以復制文件,也可以使用軟連接。
其它
如上,如果是 Python3 就可以直接使用內置的 venv
模塊,其原理與上述的相同,同時通過 pyvenv.cfg
配置文件來標識原始的 home 位置,該文件的內容如下。
home = /usr/bin include-system-site-packages = false version = 3.6.8
如果 include-system-site-packages
為 true
,解釋器啟動時就會將系統的庫添加到 sys.path
裡面,這樣在虛擬環境就可以 import
系統中安裝的包瞭。
註意,Python3 提供的 venv
模塊隻能根據當前版本創建,不能支持 Python2 。
參考 Virtualenv 官方文檔,細節可以參考該文檔。
Creation of virtual environments Python3 提供的 venv 介紹,包括常見參數以及配置文件。
← Older
到此這篇關於Python 虛擬環境工作原理解析的文章就介紹到這瞭,更多相關Python 虛擬環境原理內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 虛擬環境及venv和virtualenv的區別說明
- Python 中如何使用 virtualenv 管理虛擬環境
- pycharm設置虛擬環境與更換鏡像教程
- python 虛擬環境的創建與使用方法
- Python 虛擬環境venv詳解