问题简要描述
创建venv后(通过python -m venv .venv/
或virtualenv .venv/
),将创建一个文件树。有一个文件.venv/bin/python
或python3
,python3.<x>
。它是一个到/usr/bin/python
的unix符号链接。但如何使用venv的导入搜索路径启动此符号链接?
∮我的努力∮
解决这个问题的资源很少,但我做了一些实验:
这两个条目的sys.path
值:
对于\usr\bin\python
>>> import sys
>>> sys.path
['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/usr/lib/python3.10/site-packages']
对于/path/to/venv/bin/python
>>> import sys
>>> sys.path
['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/path/to/venv/lib/python3.10/site-packages']
但是当我创建一个目录/path/to/empty/
并运行ln -s /usr/bin/python /path/to/empty/bin/python
时,/path/to/empty
的结构如下所示:
$ tree .
.
├── bin
│ └── python -> /usr/bin/python
└── lib
└── python3.10
└── site-packages
这些子空目录都是手动创建的。
当我启动/path/to/empty/bin/python
时
>>> import sys
>>> sys.path
['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/usr/lib/python3.10/site-packages']
与/usr/bin/python
和/path/to/empty/bin/python
相比没有差异。
根据我对unix可执行文件的了解,在不提供参数的情况下,可执行文件可以访问的信息只有环境变量、当前工作目录(可以看作是一个特殊的环境变量),没有其他信息。
在上面的实验中,这些可执行项在完全相同的bash控制台中启动,没有任何预设的本地环境变量,并且似乎也不受当前工作目录的影响(根据/path/to/empty/
)。
一般问题
这说明Unix符号链接隐藏了一些强大的特性,是真的吗?
对于用户来说,符号链接有哪些超出硬链接的额外功能.
如果是,如何利用这些强大的功能?
1条答案
按热度按时间ykejflvf1#
这并不是Unix符号链接中隐藏的超级能力的产物,当你运行
python -m venv .venv/
或virtualenv .venv/
时,你会发现.venv/pyvenv.cfg
已经为你创建好了,当你启动python可执行文件时,它会在初始化过程中自动导入site
模块,这个模块会自动设置你的搜索路径,根据它的documentation:如果名为“pyvenv.cfg”的文件存在于sys.executable之上的目录中,sys.prefix和sys.exec_prefix被设置为该目录,并且还检查该目录是否存在站点包(sys.base_prefix和sys.base_exec_prefix将始终是Python安装的“真实的”前缀)。如果“pyvenv.cfg”(引导配置文件)包含设置为“true”(不区分大小写)以外的任何值的关键字“include-system-site-packages”,则不会在系统级别前缀中搜索站点程序包;否则他们会的。
一些测试证明:
/usr/bin/python -c import sys; print(sys.path)
将导致['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/usr/lib/python3.10/site-packages']
,因为python可执行文件上方的目录中不存在pyvenv.cfg
文件。.venv/bin/python -c 'import sys; print(sys.path)'
会导致['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/path/to/venv/lib/python3.10/site-packages']
,因为pyvenv.cfg
文件是在正确的位置自动创建的,并且site
模块找到了该文件。.venv/bin/python -S -c 'import sys; print(sys.path)'
会导致['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/usr/lib/python3.10/site-packages']
,因为使用-S
会禁用site
的自动导入,因此它不会查找pyvenv.cfg
。如果删除
pyvenv.cfg
文件,可以看到site
模块没有像以前那样修改搜索路径:.venv/bin/python -c 'import sys; print(sys.path)'
(不含-S
)的结果为['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/usr/lib/python3.10/site-packages']
。