Как активация виртуальной среды Python изменяет sys.path? - PullRequest
0 голосов
/ 25 февраля 2019

Я создаю свою виртуальную среду Python, используя:

python3 -m venv venv3

для активации, I 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 [ ! "$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

Я вижу, как он модифицирует $ 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, которые установлены.Я бы подумал, что это главная особенность виртуальной среды, но я не вижу, где она установлена.

Я не пытаюсь достичь чего-либо - в основном просто любопытно.

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

sys.path инициируется в site.py, он задается с использованием относительного пути sys.prefix, который является путем к исполняемому файлу python внутри виртуальной среды.

при условии, что вы используете virtualenvвместо -m venv доступ к общесистемным пакетам сайтов контролируется с помощью файла флага с именем no-global-site-packages.txt в каталоге сайта виртуальной среды.

, если виртуальная среда создается без option --system-site-packages, файл с именем no-global-site-packages.txt будет записан в каталог site venv.

во время запуска Python, site.py будет выполнен, он будет проверить наличие из no-global-site-packages.txt, если этот файл флага не существует, общесистемный путь к пакету сайта будет добавлен к sys.path, который получен из sys.real_prefix.site.py в venv, созданном virtualenv, является модифицированной версией .

надеюсь, что это может ответить на ваш вопрос.

0 голосов
/ 25 февраля 2019

Короткий ответ: активация виртуальной среды не меняет sys.path.sys.path определяется после запуска Python;см. https://docs.python.org/3.7/library/sys.html#sys.path. Виртуальная среда изменяет переменную среды PATH, изменяя то, что на самом деле выполняет интерпретатор, когда вы просто запускаете python.

.
...