繁体   English   中英

Python 虚拟环境符号链接如何工作?

[英]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 sitepip show <package>检查了路径,并得到了与没有设置环境变量时相同的响应。 从这些信息中我得出结论,python 和 pip 可能不注意环境变量。

然后,我将系统的python3pip3可执行文件符号链接到本地目录,并从使用这些( ./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 会优先使用执行文件的路径(即使那是符号链接),并且知道从可执行文件的上一个目录查找虚拟环境配置文件。 如果路径是符号链接并且没有产生有效路径,则看起来它能够返回到实际执行文件的路径。

(这与sinorocPEP 405 – Python Virtual Environments的总结一致,是我胡闹的时候写的)

这当然是演绎的。 源代码也将提供明确的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM