Python: виртуальное окружение, виртуальная среда

Статья расскажет, зачем нужна виртуальная среда в проектах на Python. Что это такое, как она используется, на что стоит обратить внимание.

Виртуальное окружение — для чего оно?

Язык программирования Python, как многие другие языки, обладает своим уникальным способом загрузки и хранения пакетов (модулей). Это имеет как плюсы, так и минусы. Дело в том, что есть несколько расположений, где сохраняются пакеты, установленные в системе. Большая часть их хранится в дочернем каталоге пути, а он, в свою очередь, находится в sys.prefix.

На том же Маке можно без проблем найти, где конкретно sys.prefix указывает на применение оболочки Python:

Нас интересуют в большей мере сторонние пакеты, которые установлены посредством easy_install либо pip install. В большинстве случаев они находятся в одной из директорий, на которую указывает site.getsitepackages:

Все эти нюансы следует знать, чтобы понимать ситуацию, ведь по дефолту каждый системный объект станет применять одинаковые каталоги при хранении пакетов. Может показаться, что это несущественно. Да, если речь идёт о системных пакетах, которые считаются частью стандартной библиотеки. Совсем другое дело, если речь идёт о сторонних пакетах.

Представьте простую ситуацию: у вас 2 пакета (ProjectA and ProjectB). Оба связаны зависимостью с одной и той же библиотекой — ProjectC. Если же мы начнём запрашивать различные версии ProjectC, могут возникнуть затруднения. ProjectA может запросить одну версию (1.0), а ProjectB — другую, более новую (2.0). В этом и заключается большая проблема «Питона» — он не различает версии в каталоге «site-packages».

Раз проекты хранятся с учётом их названий, различий между версиями нет, в результате чего ProjectA и ProjectB будут применять одну и ту же версию, а это не есть хорошо.

Как раз здесь на сцену и выходит виртуальное окружение (среда) Python, делая это совместно с инструментами virtualenv/ven.

Так что же такое виртуальное окружение (virtual environment)?

Основной задачей виртуального окружения в языке Python является создание изолированной среды для «Пайтон»-проектов. Что это значит: — любой проект способен иметь собственные зависимости; — зависимости второго проекта не оказывают влияния на зависимости первого и наоборот.

Если вернуться к примеру выше, становится очевидным, что следует просто разделить виртуальные окружения для ProjectA и ProjectB. В итоге каждая отдельная среда будет зависеть от любой версии ProjectC и не зависеть друг от друга.

Профит налицо, ведь отсутствуют ограничения на то, во скольких экземплярах будет виртуальное окружение, ведь они являются обычными директориями, где содержится несколько скриптов. А ещё их довольно легко создать, используя средства командной строки — речь идёт об инструментах virtualenv либо pyenv для Python.

Применение виртуальной среды

Если у вас Python 3, модуль venv должен быть уже установлен. Если же нет, вопрос можно решить, выполнив установку Python-инструмента virtualenv посредством pip:

Внимание! Следует понимать, что venv и virtualenv — это, по сути, 2 разных инструмента, имеющих несколько различий в плане команд.

Создадим новый каталог, с которым потом станем работать, следующей командой:

Теперь создадим новое виртуальное окружение внутри каталога:

Внимание! По дефолту ни один из существующих сторонних пакетов не включён.

В Python 3 подход venv имеет преимущество, вынуждающее применять определённую версию Python-интерпретатора, который нужен для создания виртуальной среды. Зато вы избежите проблем, выясняя, какая именно инсталляция «Пайтон» базируется в новом виртуальном окружении.

Начиная с версий 3.3 и 3.4, рекомендуется создавать окружение посредством pyvenv в командной строке (данный инструмент также включён в инсталляционный пакет «Пайтона» по дефолту). Но уже с 3.6 и далее потребуется python3 -m venv.

В вышеуказанном примере данная команда создаст каталог «env», структура которого будет выглядеть приблизительно так:

Разберём, что в папках, подробнее: • bin – это файлы, взаимодействующие с виртуальным окружением; • include – это С-заголовки, которые компилируют Python-пакеты; • lib – это копия Python-версии совместно с папкой «site-packages», где находится каждая зависимость.

Идём дальше. У нас в наличии копии (символические ссылки) ряда Python-инструментов. Данные файлы применяются, чтобы команды и «Пайтон»-код выполнялись в контексте созданной среды, что позволяет достичь изоляции от глобальной среды.

Весьма интересны скрипты activate, находящиеся в bin. Они применяются в целях настройки вашей оболочки для применения исполняемого файла окружения «Пайтон» и его сайтовых пакетов по дефолту.

Для использования этих пакетов среды в условиях изоляции, надо их активировать, выполнив активацию простой командой:

Здесь важно учесть, что ваше приглашение командной строки уже носит префикс вашего окружения (для нашего примера это env). Речь идёт об индикаторе, свидетельствующем, что в данный момент времени env активен. Это, в свою очередь, подтверждает то, что выполнимые «Пайтон»-файлы задействуют пакеты и настройки лишь из этого виртуального окружения.

Если надо показать изолированный пакет, что называется, в деле, подойдёт модуль bcrypt. Давайте скажем, что он установлен где-то в системе, а не в нашем виртуальном окружении.

Перед проверкой вернёмся назад в контекст «system» с помощью команды deactivate:

Теперь сеанс оболочки вернулся в нормальное состояние, а команда python будет ссылаться на общую Python-инсталляцию. Сделать это можно, когда заблагорассудиться, но после того, как закроете определённое виртуальное окружение. Далее следует установить bcrypt и воспользоваться им в целях хэширования пароля:

А теперь давайте посмотрим, что случится, если попробовать ту же самую команду, когда виртуальное окружение активно:

Видно, что поведение команды python -c «import bcrypt…» меняется после вызова source env/bin/activate. Если в одном примере мы имеем доступный нам bcrypt, то в другом — нет. Это и является тем типом разделения, который нам нужен для создания виртуального окружения, его запуска и работы, то есть мы к нему и пришли.

По материалам статьи «Python Virtual Environments: A Primer».