Как создать и использовать виртуальное окружение Python

Разбираемся с виртуальным окружением для интерпретатора Python. Учимся создавать, активировать, деактивировать, клонировать и удалять виртуальные среды вручную и с помощью алиасов bash.

Виртуальное окружение python - это механизм организации изолированных сред Python. Разработчик создает для проекта автономную директорию-среду с подходящей версией интерпретатора Python, зависимостями ядра и нужными сторонними пакетами. Такой подход уменьшает риск поломок в основной системе и позволяет работать с пакетами разных версий без конфликтов. Также виртуальные среды просто клонировать при переносе софта в другое место, например, на боевой сервер.

Но виртуальное окружение занимает дополнительное место на накопителях. Для примера, python окружение небольшого сайта на Django занимает 120-150 мегабайт. А если работаем с библиотеками для NLP, то размер виртуальной среды вырастет до 500-1000 мегабайт и даже больше.

Виртуальные среды Python обеспечивают эффективный способ управления множеством библиотек и пакетов, обеспечивая согласованность приложений.

Как создать виртуальное окружение python

Для создания виртуального окружения python применяем команду

$ python -m venv env

Эта команда создает директорию env, внутри которой организует структуру новой изолированной среды python. Теперь в env/bin лежат исполняемые файлы activate, pip, easy_install и символические ссылки на системные интерпретаторы python. В директории env/lib/python*/site-packages размещаются зависимости и сторонние пакеты.

Модуль venv поддерживает опции.

--prompt задает приглашение, которое отображается в консоли при активной виртуальной среде. Для примера python -m venv --prompt django env.

--clear удаляет содержимое директории виртуального окружения перед установкой новой среды. Для примера python -m venv --clear env.

--upgrade обновляет виртуальное окружение для использования с новой или другой версией python. Опцию применяют после изменения системного интерпретатора python. Для примера python -m venv --upgrade env.

--upgrade-deps обновляет pip и setuptools в виртуальном окружении. Для примера python -m venv --upgrade-deps env.

Остальные опции доступны по команде python -m venv --help

Как активировать виртуальное окружение

В директории env/bin лежат скрипты активации виртуального окружения.

В Unix и MacOS в терминале bash виртуальную среду python активируют командой

$ source ./env/bin/activate

Для упрощения вместо команды source используют точку:

$ . ./env/bin/activate

Для оболочек csh и fish используют скрипты env/bin/activate.csh и env/bin/activate.fish соответственно.

В Windows виртуальную среду python активируют так:

env\Scripts\activate.bat

Как деактивировать виртуальную среду

Скрипт активации виртуального окружения создает функцию deactivate, которую можно вызвать для деактивации среды в оболочке.

$ deactivate

После деактивации python будет работать в системном окружении.

Как удалить виртуальное окружение

Для удаления среды просто удаляют директорию с ней. Но сначала активное окружение деактивируют.

(env)$ deactivate
$ rm -r env

Как клонировать виртуальное окружение python

В активированном виртуальном окружении, которое нужно клонировать, создают файл со списком всех пакетов и деактивируют среду. Далее этот файл используют для установки пакетов в новой виртуальной среде.

(old-env)$ pip freeze > requirements.txt
...
(new-env)$ pip install -r requirements.txt

Как обновить пакеты python через pip

Для начала определяем устаревшие пакеты. Активируем виртуальное окружение и выполняем команду

(env)$ pip list --outdated

Команда выведет пакеты python, которые требуют обновления. Если пакетов немного, то обновляем их вручную. Для этого используем флаг --upgrade или -U с операцией install

(env)$ pip install -U pip setuptools
(env)$ pip install -U Django

Если пакетов много, то автоматизируем процесс. Вот пример для оболочки bash с awk:

(env)$ pip list --outdated | awk 'NR>2 {print $1}' | xargs pip install -U

Команда обновит все пакеты виртуальной среды python до самых последних версий. Для тех же целей подойдет вот такой вариант:

(env)$ pip list --outdated | awk 'NR>2 {print $1"=="$3}' | xargs pip install

Иногда нужно контролировать процесс обновления, чтобы обновить не все пакеты. В этом случае сохраняем список установленных пакетов в отдельный файл и удаляем строки с пакетами, которые не нужно обновлять. Далее обновляем пакеты и фиксируем версии в requiremets.txt. Вот пример для терминала bash:

(env)$ pip list --outdated | awk 'NR>2 {print $1"=="$3}' > /tmp/r.txt
(env)$ pip install -r /tmp/r.txt
(env)$ pip freeze -r requierements.txt > requirements.txt

Перед обновлением читаем нотации об изменениях в пакетах. Особенно внимательно работаем при смене мажорной версии. Перед обновлением виртуальных сред на боевых серверах обязательно тестируем изменения на dev машинах.

Как найти и удалить ненужные пакеты python в pip

В процессе эксплуатации в виртуальном окружении накапливаются пакеты, которые не нужны для проекта. Например, поставили пакет ipython и его зависимости. Позже удалили ipython, а зависимости остались. Чтобы найти пакеты, от которых не зависят другие используем команду:

(env)$ pip list --not-required

Выбираем из этого списка пакеты, которые больше не нужны для проекта и удаляем.

(env)$ pip uninstall ipython ipython-genutils

Чтобы получить информацию о пакете с зависимостями используем команду pip show

(env)$ pip show pydantic
Name: pydantic
Version: 1.10.5
Summary: Data validation and settings management using python type hints
Home-page: https://github.com/pydantic/pydantic
Author: Samuel Colvin
Author-email: s@muelcolvin.com
License: MIT
Location: /usr/bin/python3.9/site-packages
Requires: typing-extensions
Required-by: pydantic-xml

Бонус: алиасы для управления виртуальным окружением

Для комфортной работы с виртуальными средами python часто используют virtualenvwrapper. Он создает все директории виртуальных окружений в одном месте и предоставляет удобные команды для создания, активации и деактивации сред.

Но иногда используют самописные решения. Я работаю с оболочкой bash под Debian и использую 4 алиаса: cenv, venv, denv, rmenv. Эти команды работают с виртуальным окружением в текущей или в общей директории ~/.venvs

Также использую эти 4 алиаса на серверах для деплоя Django, Flask и других python приложений. Мне удобно и решение работает без лишних пакетов в системе.

Алиас cenv - create env

Команда cenv создает виртуальное окружение python env в текущей директории или, если указать параметр, в ~/.venvs.

alias cenv='__a(){ [[ -n $1 ]] && A="$HOME/.venvs/$1" || A="."; [[ -d $A/env ]] && echo "env exists" || (mkdir -p $A; python3 -mvenv --upgrade-deps $A/env > /dev/null && echo "$A/env created"); unset -v A; unset -f __a; }; __a'

Алиас venv - virtual env

Команда venv активирует виртуальное окружение python env в текущей директории или, если указать параметр, в ~/.venvs.

alias venv='__a(){ [[ -n $1 ]] && A="$HOME/.venvs/$1/env/" || A="./env"; [[ -f $A/bin/activate ]] && source $A/bin/activate && echo "$A activated" || echo "$A not exists" ; unset $A; unset -v A; unset -f __a; }; __a'

Алиас denv - deactivate env

Команда denv деактивирует виртуальное окружение python.

alias denv='[[ "$(type -t deactivate)" == "function" ]] && deactivate'

Алиас rmenv - remove env

Команда rmenv удаляет директорию с виртуальным окружением env в текущем каталоге или в ~/.venvs

alias rmenv='__a(){ [[ -n $1 ]] && A="$HOME/.venvs/$1" || A="./env"; [[ "$(type -t deactivate)" == "function" ]] && deactivate; [[ -d $A ]] && rm -r $A && echo "$A removed"; unset -v A; unset -f __a; }; __a'

Как использовать эти алиасы

В оболочке bash предусмотрели специальный файл ~/.bash_aliases для пользовательских команд-псевдонимов. Алиасы можно добавить туда. Но можно прописать и в другие стартовые сценарии оболочки.

alias cenv='__a(){ [[ -n $1 ]] && A="$HOME/.venvs/$1" || A="."; [[ -d $A/env ]] && echo "env exists" || (mkdir -p $A; python3 -mvenv --upgrade-deps $A/env > /dev/null && echo "$A/env created"); unset -v A; unset -f __a; }; __a'
alias venv='__a(){ [[ -n $1 ]] && A="$HOME/.venvs/$1/env/" || A="./env"; [[ -f $A/bin/activate ]] && source $A/bin/activate && echo "$A activated" || echo "$A not exists" ; unset $A; unset -v A; unset -f __a; }; __a'
alias denv='[[ "$(type -t deactivate)" == "function" ]] && deactivate'
alias rmenv='__a(){ [[ -n $1 ]] && A="$HOME/.venvs/$1" || A="./env"; [[ "$(type -t deactivate)" == "function" ]] && deactivate; [[ -d $A ]] && rm -r $A && echo "$A removed"; unset -v A; unset -f __a; }; __a'

Запускаем файл ~/.bash_aliases

$ source ~/.bash_aliases

Теперь можно применять новые команды для быстрой работы с виртуальным окружением python.

Разделы: Python

Автор: stan / 15 Фев 2023