激活 python 虚拟环境如何修改 sys.path?
How does activating a python virtual environment modify sys.path?
我使用以下方法创建 python 虚拟环境:
python3 -m venv venv3
要激活,我source venv3/bin/activate
。
venv3/bin/activate
看起来并没有那么复杂:
# This file must be used with "source bin/activate" *from bash*
# you cannot run it directly
deactivate () {
# reset old environment variables
if [ -n "$_OLD_VIRTUAL_PATH" ] ; then
PATH="$_OLD_VIRTUAL_PATH"
export PATH
unset _OLD_VIRTUAL_PATH
fi
if [ -n "$_OLD_VIRTUAL_PYTHONHOME" ] ; then
PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME"
export PYTHONHOME
unset _OLD_VIRTUAL_PYTHONHOME
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
hash -r
fi
if [ -n "$_OLD_VIRTUAL_PS1" ] ; then
PS1="$_OLD_VIRTUAL_PS1"
export PS1
unset _OLD_VIRTUAL_PS1
fi
unset VIRTUAL_ENV
if [ ! "" = "nondestructive" ] ; then
# Self destruct!
unset -f deactivate
fi
}
# unset irrelevant variables
deactivate nondestructive
VIRTUAL_ENV="/home/pi/django-test/venv3"
export VIRTUAL_ENV
_OLD_VIRTUAL_PATH="$PATH"
PATH="$VIRTUAL_ENV/bin:$PATH"
export PATH
# unset PYTHONHOME if set
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
# could use `if (set -u; : $PYTHONHOME) ;` in bash
if [ -n "$PYTHONHOME" ] ; then
_OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME"
unset PYTHONHOME
fi
if [ -z "$VIRTUAL_ENV_DISABLE_PROMPT" ] ; then
_OLD_VIRTUAL_PS1="$PS1"
if [ "x(venv3) " != x ] ; then
PS1="(venv3) $PS1"
else
if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
# special case for Aspen magic directories
# see http://www.zetadev.com/software/aspen/
PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1"
else
PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1"
fi
fi
export PS1
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
hash -r
fi
我可以看到它修改了 $PATH 和 $PS1,创建了一个 deactivate
函数,甚至备份了它修改的旧变量,以便在用户运行 deactivate
函数。这一切都是有道理的。
我没有看到的一件事是 python 的 sys.path 被修改的地方。在我的系统上,这是我看到的:
sys.path 虚拟环境外:
['', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-arm-linux-gnueabihf', '/usr/lib/python3.5/lib-dynload', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python3/dist-packages']
sys.path 虚拟环境内部:
['', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-arm-linux-gnueabihf', '/usr/lib/python3.5/lib-dynload', '/home/pi/django-test/venv3/lib/python3.5/site-packages']
显然,sys.path 在某个时候以某种方式被修改了。这是有道理的,因为这就是 python 知道在哪里可以找到安装的第三方 python 库的方式。我认为这是虚拟环境的主要特征,但我看不到它是在哪里设置的。
我并不想完成任何事情 - 主要是好奇。
简短的回答是激活虚拟环境不会改变sys.path
。 sys.path
是在Python一开机就确定的;参见 https://docs.python.org/3.7/library/sys.html#sys.path。虚拟环境所做的,通过调整你的 PATH
环境变量,当你简单地 运行 python
.
时改变解释器实际上 运行s
sys.path
在site.py
中启动,使用sys.prefix
的相对路径设置,即python可执行文件在虚拟环境中的路径。
假设您使用的是 virtualenv
,而不是 -m venv
,对系统范围站点包的访问由虚拟站点目录下名为 no-global-site-packages.txt
的标志文件控制环境。
如果创建的虚拟环境没有选项--system-site-packages
,一个名为no-global-site-packages.txt
will be written的文件进入site
目录来自 venv.
在python启动时,执行site.py
,会check the existence of no-global-site-packages.txt
,如果这个标志文件不存在,系统范围的站点包路径将是添加到 sys.path
,这是从 sys.real_prefix
推断出来的。 site.py
在 virtualenv 中创建的 venv 是 a modified version.
希望这可以回答您的问题。
我使用以下方法创建 python 虚拟环境:
python3 -m venv venv3
要激活,我source venv3/bin/activate
。
venv3/bin/activate
看起来并没有那么复杂:
# This file must be used with "source bin/activate" *from bash*
# you cannot run it directly
deactivate () {
# reset old environment variables
if [ -n "$_OLD_VIRTUAL_PATH" ] ; then
PATH="$_OLD_VIRTUAL_PATH"
export PATH
unset _OLD_VIRTUAL_PATH
fi
if [ -n "$_OLD_VIRTUAL_PYTHONHOME" ] ; then
PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME"
export PYTHONHOME
unset _OLD_VIRTUAL_PYTHONHOME
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
hash -r
fi
if [ -n "$_OLD_VIRTUAL_PS1" ] ; then
PS1="$_OLD_VIRTUAL_PS1"
export PS1
unset _OLD_VIRTUAL_PS1
fi
unset VIRTUAL_ENV
if [ ! "" = "nondestructive" ] ; then
# Self destruct!
unset -f deactivate
fi
}
# unset irrelevant variables
deactivate nondestructive
VIRTUAL_ENV="/home/pi/django-test/venv3"
export VIRTUAL_ENV
_OLD_VIRTUAL_PATH="$PATH"
PATH="$VIRTUAL_ENV/bin:$PATH"
export PATH
# unset PYTHONHOME if set
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
# could use `if (set -u; : $PYTHONHOME) ;` in bash
if [ -n "$PYTHONHOME" ] ; then
_OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME"
unset PYTHONHOME
fi
if [ -z "$VIRTUAL_ENV_DISABLE_PROMPT" ] ; then
_OLD_VIRTUAL_PS1="$PS1"
if [ "x(venv3) " != x ] ; then
PS1="(venv3) $PS1"
else
if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
# special case for Aspen magic directories
# see http://www.zetadev.com/software/aspen/
PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1"
else
PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1"
fi
fi
export PS1
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
hash -r
fi
我可以看到它修改了 $PATH 和 $PS1,创建了一个 deactivate
函数,甚至备份了它修改的旧变量,以便在用户运行 deactivate
函数。这一切都是有道理的。
我没有看到的一件事是 python 的 sys.path 被修改的地方。在我的系统上,这是我看到的:
sys.path 虚拟环境外:
['', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-arm-linux-gnueabihf', '/usr/lib/python3.5/lib-dynload', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python3/dist-packages']
sys.path 虚拟环境内部:
['', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-arm-linux-gnueabihf', '/usr/lib/python3.5/lib-dynload', '/home/pi/django-test/venv3/lib/python3.5/site-packages']
显然,sys.path 在某个时候以某种方式被修改了。这是有道理的,因为这就是 python 知道在哪里可以找到安装的第三方 python 库的方式。我认为这是虚拟环境的主要特征,但我看不到它是在哪里设置的。
我并不想完成任何事情 - 主要是好奇。
简短的回答是激活虚拟环境不会改变sys.path
。 sys.path
是在Python一开机就确定的;参见 https://docs.python.org/3.7/library/sys.html#sys.path。虚拟环境所做的,通过调整你的 PATH
环境变量,当你简单地 运行 python
.
sys.path
在site.py
中启动,使用sys.prefix
的相对路径设置,即python可执行文件在虚拟环境中的路径。
假设您使用的是 virtualenv
,而不是 -m venv
,对系统范围站点包的访问由虚拟站点目录下名为 no-global-site-packages.txt
的标志文件控制环境。
如果创建的虚拟环境没有选项--system-site-packages
,一个名为no-global-site-packages.txt
will be written的文件进入site
目录来自 venv.
在python启动时,执行site.py
,会check the existence of no-global-site-packages.txt
,如果这个标志文件不存在,系统范围的站点包路径将是添加到 sys.path
,这是从 sys.real_prefix
推断出来的。 site.py
在 virtualenv 中创建的 venv 是 a modified version.
希望这可以回答您的问题。