[英]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.