[英]How do Python Virtual Environment Symlinks Work?
如果我像這樣創建一個 Python 虛擬環境:
$ python3 -m venv my_venv
...然后查看 bin 目錄中的 Python 二進制文件,如下所示:
$ ls -l my_env/bin/python*
lrwxrwxrwx 1 fred fred 7 Sep 12 15:57 my_env/bin/python -> python3
lrwxrwxrwx 1 fred fred 16 Sep 12 15:57 my_env/bin/python3 -> /usr/bin/python3
我看到python
鏈接到主要的全局python
。 因此,什么機制可以確保我們在激活虛擬環境后安裝的 Python 包安裝到site-packages
?
我很感興趣,所以我做了一些搜索並進行了一些實驗。 參考: 如何找到我的 Python 站點包目錄的位置?
我在 /tmp 中創建了一個虛擬環境 my_venv 並沒有激活它。 在 Linux 上激活虛擬環境( my_venv/bin/activate
)將虛擬環境的bin
目錄添加到路徑中; 我發現我可以通過使用完整路徑來模擬它; 即,直接執行./my_venv/bin/python
和./my_venv/bin/pip
。 此類實驗的結果:
> ################### system executables
> python3 -m site # system's python
sys.path = [
<current directory>
'/usr/lib/python310.zip',
'/usr/lib/python3.10',
'/usr/lib/python3.10/lib-dynload',
'/usr/local/lib/python3.10/dist-packages',
'/usr/lib/python3/dist-packages',
]
> pip3 show <a package> # system's pip
...
Location: /usr/lib/python3/dist-packages
...
> pip3 show <package installed in the venv>
WARNING: Package(s) not found
> ################### venv executables
> /tmp/my_venv/bin/python3 -m site
sys.path = [
<current directory>
'/usr/lib/python310.zip',
'/usr/lib/python3.10',
'/usr/lib/python3.10/lib-dynload',
'/tmp/my_venv/lib/python3.10/site-packages
]
> /tmp/my_venv/bin/pip3 show <package installed in the venv>
...
Location: /tmp/my_venv/lib/python3.10/site-packages
...
> /tmp/my_venv/bin/pip3 show <package installed on the system>
WARNING: Package(s) not found
我看了看激活腳本/tmp/my_venv/bin/activate
。 它設置了幾個環境變量,特別是一個名為VIRTUAL_ENV
的環境變量。 我將此環境變量設置為我的虛擬環境的路徑,因為如果我激活了虛擬環境,它就會被設置。 然后我使用系統的python -m site
和pip show <package>
檢查了路徑,並得到了與沒有設置環境變量時相同的響應。 從這些信息中我得出結論,python 和 pip 可能不注意環境變量。
然后,我將系統的python3
和pip3
可執行文件符號鏈接到本地目錄,並從使用這些( ./python3
和./pip3
)的命令中獲得了與我從系統可執行文件中獲得的相同響應。
然后我創建了以下目錄結構:
bin/python3 # symlink to system python3
bin/pip3 # symlink to system pip3
lib/python3.10/site-packages/
這些仍然給了我系統路徑。 但是,一旦我將文件pyvenv.cfg
從虛擬環境復制到我的目錄結構中,它就開始使用我的本地路徑!
注意:我直接從真實的虛擬環境中復制了 pyvenv.cfg,沒有對其進行更改。 該文件包含行“home = /usr/bin/”。
我得出的結論是,為了確定站點包的路徑,Python 會優先使用執行文件的路徑(即使那是符號鏈接),並且知道從可執行文件的上一個目錄查找虛擬環境配置文件。 如果路徑是符號鏈接並且沒有產生有效路徑,則看起來它能夠返回到實際執行文件的路徑。
(這與sinoroc對PEP 405 – Python Virtual Environments的總結一致,是我胡鬧的時候寫的)
這當然是演繹的。 源代碼也將提供明確的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.