激活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
似乎并不那么复杂:
#此文件必须与源bin/激活"一起使用* from bash *#您不能直接运行它停用(){#重置旧的环境变量如果[-n"$ _OLD_VIRTUAL_PATH"];然后PATH ="$ _ OLD_VIRTUAL_PATH"导出路径未设置_OLD_VIRTUAL_PATH科幻如果[-n"$ _OLD_VIRTUAL_PYTHONHOME"];然后PYTHONHOME ="$ _ OLD_VIRTUAL_PYTHONHOME"导出PYTHONHOME未设置_OLD_VIRTUAL_PYTHONHOME科幻#这应该检测bash和zsh,它们具有必须执行的hash命令#被调用以使其忘记过去的命令.不忘#过去的命令可能不会尊重我们对$ PATH所做的更改如果[-n"$ BASH" -o -n"$ ZSH_VERSION"];然后哈希-r科幻如果[-n"$ _OLD_VIRTUAL_PS1"];然后PS1 ="$ _ OLD_VIRTUAL_PS1"出口PS1未设置_OLD_VIRTUAL_PS1科幻未设置VIRTUAL_ENV如果 [ !"$ 1" =非破坏性"];然后# 自毁!取消设置-f停用科幻}#设置不相关的变量停用非破坏性VIRTUAL_ENV ="/home/pi/django-test/venv3"汇出VIRTUAL_ENV_OLD_VIRTUAL_PATH ="$ PATH"PATH ="$ VIRTUAL_ENV/bin:$ PATH"导出路径#取消设置PYTHONHOME#如果将PYTHONHOME设置为空字符串,则此操作将失败(无论如何都是错误的)#可以在bash中使用`if(set -u;:$ PYTHONHOME);`如果[-n"$ PYTHONHOME"];然后_OLD_VIRTUAL_PYTHONHOME ="$ PYTHONHOME"未设定PYTHONHOME科幻如果[-z"$ VIRTUAL_ENV_DISABLE_PROMPT"];然后_OLD_VIRTUAL_PS1 ="$ PS1"如果["x(venv3)"!= x];然后PS1 =(venv3)$ PS1"别的如果[`basename \" $ VIRTUAL_ENV \`" ="__"];然后#Aspen魔术目录的特殊情况#参见http://www.zetadev.com/software/aspen/PS1 ="[`basename \`dirname \" $ VIRTUAL_ENV \"\"] $ PS1别的PS1 =(`basename \" $ VIRTUAL_ENV \`)$ PS1"科幻科幻出口PS1科幻#这应该检测bash和zsh,它们具有必须执行的hash命令#被调用以使其忘记过去的命令.不忘#过去的命令可能不会尊重我们对$ PATH所做的更改如果[-n"$ BASH" -o -n"$ ZSH_VERSION"];然后哈希-r科幻
我可以看到它修改了$ 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
在 site.py
中启动,它使用 sys.prefix
,它是虚拟环境中python可执行文件的路径.
假设您使用的是 virtualenv
,而不是 -m venv
,则使用名为 no-global的标志文件控制对系统级站点包的访问-site-packages.txt
,位于虚拟环境的站点目录下.
如果创建的虚拟环境没有选项-system-site-packages
,则文件名为 no-global-site-packages.txt 代码> 将被写入到
venv的站点
目录.
在python启动期间,将执行 site.py
,它将修改版.>
希望这可以回答您的问题.
I create my python virtual environment using:
python3 -m venv venv3
to activate, I source venv3/bin/activate
.
venv3/bin/activate
doesn't appear to be all that complex:
# 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 [ ! "$1" = "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
I can see it modifying $PATH, and $PS1, creating a deactivate
function, and even backing up old variables that it modifies so it can restore them when the user runs the deactivate
function. All this makes sense.
The one thing I don't see is where python's sys.path is modified. On my system, this is what I see:
sys.path outside of virtual environment:
['', '/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 inside of virtual environment:
['', '/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']
Clearly, sys.path gets modified at some point, somehow. This makes sense, since that's how python knows where to find the third-party python libraries that are installed. I would think that this is the main feature of the virtual environment, but I can't see where it gets set.
I'm not trying to accomplish anything - mostly just curious.
sys.path
is initiated in site.py
, it is set using the relative path of sys.prefix
, which is the path of python executable inside the virtual environment.
assuming you are using virtualenv
, rather than -m venv
, access to system-wide site-packages is controlled with a flag file named no-global-site-packages.txt
, under site dir of the virtual environment.
if the virtual environment is created without option --system-site-packages
, a file named no-global-site-packages.txt
will be written into the site
dir of venv.
during python startup, site.py
is executed, it will check the existence of no-global-site-packages.txt
, if this flag file not exists, system-wide site package path will be added to sys.path
, which is infered from sys.real_prefix
. site.py
in a virtualenv created venv is a modified version.
hope this could answer your question.
这篇关于激活python虚拟环境如何修改sys.path?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!