Понимание того, как работает Python virtualenv, — это одна из вещей, которую вам следует знать, когда вы начинаете работать с Python.
Python virtualenv создает изолированную среду, в которой вы можете установить все зависимости Python, необходимые для вашего проекта. Если вы работаете над несколькими проектами, требующими различных зависимостей, использование виртуальных сред позволяет хранить эти среды отдельно. Это также позволяет иметь среду, которая не мешает глобальной системе Python.
В этом руководстве вы узнаете, что вам нужно, чтобы начать использовать virtualenv для ваших проектов. Мы рассмотрим практические примеры, которые помогут вам понять, как работает virtualenv.
Virtualenv… поехали!
Зачем использовать виртуальную среду в Python
Как объяснялось в предыдущем разделе, Python virtualenv позволяет создать среду, содержащую все зависимости (пакеты), необходимые Python для выполнения проектов.
Виртуальная среда — это отдельный каталог, который можно создать, как я объясню в следующем разделе.
На данный момент важной концепцией является то, что…
Использование виртуальных сред позволяет управлять несколькими проектами, не рискуя, что зависимости Python одного проекта нарушат работу другого проекта.
Простым примером является сценарий, в котором ProjectA требует версию 1.0.0 пакета, а ProjectB работает только с версией 1.1.0 того же пакета.
Запуск обоих проектов с использованием системной среды Python невозможен, и здесь на помощь может прийти virtualenv.
Как создать виртуальную среду в Python?
Примеры, которые я покажу здесь, основаны на Linux. Концепции очень похожи для Mac и Windows, некоторые команды немного отличаются в Windows.
Во-первых, я создал два псевдонима внутри .bashrc, чтобы пользователь ec2 мог ссылаться на python3 и pip3 просто как на python и pip:
alias python=python3
alias pip=pip3
Прежде всего, я проверю, установлены ли Python и PIP:
[ec2-user@host ~]$ python --version
Python 3.7.8
[ec2-user@host ~]$ pip --version
pip 9.0.3 from /usr/lib/python3.7/site-packages (python 3.7)
Как вы видите, у меня в системе Python 3.7.8 и PIP 9.0.3. Версии в вашей системе могут отличаться в зависимости от вашего дистрибутива Linux и его версии.
Первым шагом для создания виртуальной среды является установка пакета virtualenv с помощью pip:
[ec2-user@host ~]$ pip install virtualenv --user
Collecting virtualenv
Using cached https://files.pythonhosted.org/packages/1d/09/9179b676c126b2687bf4110e5b88c8c52d9113f31bd5f8f6ab97d380e434/virtualenv-20.0.30-py2.py3-none-any.whl
Requirement already satisfied: appdirs<2,>=1.4.3 in /usr/local/lib/python3.7/site-packages (from virtualenv)
Requirement already satisfied: six<2,>=1.9.0 in /usr/local/lib/python3.7/site-packages (from virtualenv)
Requirement already satisfied: distlib<1,>=0.3.1 in /usr/local/lib/python3.7/site-packages (from virtualenv)
Requirement already satisfied: importlib-metadata<2,>=0.12; python_version < "3.8" in /usr/local/lib/python3.7/site-packages (from virtualenv)
Requirement already satisfied: filelock<4,>=3.0.0 in /usr/local/lib/python3.7/site-packages (from virtualenv)
Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/site-packages (from importlib-metadata<2,>=0.12; python_version < "3.8"->virtualenv)
Installing collected packages: virtualenv
Successfully installed virtualenv-20.0.30
Флаг --user
сообщает pip о необходимости установки пакета virtualenv в локальный каталог внутри домашнего каталога текущего пользователя (ec2-user).
Эта команда не будет выполнена, если мы не передадим флаг –-user
, поскольку у ec2-user нет доступа для установки пакетов в системной библиотеке Python.
Следующая команда подтверждает, что virtualenv успешно установлен:
[ec2-user@host ~]$ virtualenv --version
virtualenv 20.0.30 from /home/ec2-user/.local/lib/python3.7/site-packages/virtualenv/__init__.py
Теперь, чтобы создать виртуальную среду, перейдите в каталог, в котором вы хотите разрабатывать свои проекты Python (в этом примере они называются проектами), и выполните следующую команду:
virtualenv codefathertech
Это создает виртуальную среду под названием codefathertech. Вот вывод на моей системе Linux:
[ec2-user@host blog]$ cd projects/
[ec2-user@host projects]$ virtualenv codefathertech
created virtual environment CPython3.7.8.final.0-64 in 909ms
creator CPython3Posix(dest=/opt/blog/projects/codefathertech, clear=False, global=False)
seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/ec2-user/.local/share/virtualenv)
added seed packages: pip==20.2.1, setuptools==49.2.1, wheel==0.34.2
activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator
Структура виртуальных сред Python
Прежде чем изучать, как использовать созданную нами виртуальную среду, давайте рассмотрим ее структуру каталогов. Для этого я использую команду tree с глубиной отображения дерева каталогов, равной 2.
Команда tree недоступна в моей системе, и я могу установить ее с помощью:
sudo yum install tree
А вот структура созданной нами виртуальной среды:
[ec2-user@host projects]$ tree -L 2 codefathertech
codefathertech
├── bin
│ ├── activate
│ ├── activate.csh
│ ├── activate.fish
│ ├── activate.ps1
│ ├── activate_this.py
│ ├── activate.xsh
│ ├── easy_install
│ ├── easy_install3
│ ├── easy_install-3.7
│ ├── easy_install3.7
│ ├── pip
│ ├── pip3
│ ├── pip-3.7
│ ├── pip3.7
│ ├── python -> /usr/bin/python3
│ ├── python3 -> python
│ ├── python3.7 -> python
│ ├── wheel
│ ├── wheel3
│ ├── wheel-3.7
│ └── wheel3.7
├── lib
│ └── python3.7
├── lib64
│ └── python3.7
└── pyvenv.cfg
5 directories, 22 files
Двоичный файл Python, который вы видите в каталоге bin, является символической ссылкой на системный двоичный файл Python 3. В каталоге bin вы также можете увидеть скрипт, который мы проанализируем в следующем разделе: activate.
При создании virtualenv он также включает в себя каталог lib, содержащий модули и пакеты .
Но как Python узнает, что пакеты нужно искать в каталоге lib внутри виртуальной среды?
Это связано с тем, что двоичный файл Python ищет каталоги lib относительно своего пути, и первый каталог lib, который он находит, — это ../lib/python3.7/.
Чтобы создать virtualenv, использующий другую версию Python, например Python 2.7, я могу использовать следующую команду:
virtualenv -p /usr/bin/python2.7 codefathertech
А теперь давайте посмотрим, как использовать созданную нами виртуальную среду!
Активировать виртуальную среду
Недостаточно создать виртуальную среду, чтобы ею пользоваться, ее необходимо еще и активировать.
Если вы не активируете virtualenv после его создания, вы все равно будете устанавливать все пакеты в общесистемном дистрибутиве Python.
Не забудьте активировать virtualenv с помощью команды source:
[ec2-user@host projects]$ source codefathertech/bin/activate
(codefathertech) [ec2-user@host projects]$
Как только вы активируете свой virtualenv, приглашение Linux изменится. Вы увидите имя виртуальной среды, заключенное в скобки слева.
Хорошо, но что на самом деле происходит при активации virtualenv?
Первое, что я хочу узнать, это какой интерпретатор Python я использую до и после активации виртуальной среды. Для этого я могу использовать команду Linux which:
До
[ec2-user@host projects]$ which python
alias python='python3'
/usr/bin/python3
После
[ec2-user@host projects]$ source codefathertech/bin/activate
(codefathertech) [ec2-user@ip-172-31-28-249 projects]$ which python
alias python='python3'
/opt/blog/projects/codefathertech/bin/python3
Как может измениться интерпретатор Python, используемый по умолчанию, после активации виртуальной среды?
Virtualenv и переменная среды PATH
Первое, что приходит мне на ум, что могло бы привести к такому результату, — это изменение значения переменной среды PATH Linux.
Переменная среды PATH перечисляет каталоги, используемые Linux для выполнения двоичных файлов, без указания их полного пути.
Быстрый способ убедиться в этом — использовать команду echo для вывода значения переменной среды PATH до и после активации Python virtualenv.
До
[ec2-user@host ~]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ec2-user/.local/bin:/home/ec2-user/bin
После
[ec2-user@host projects]$ source codefathertech/bin/activate
(codefathertech) [ec2-user@ip-172-31-28-249 projects]$ echo $PATH
/opt/blog/projects/codefathertech/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ec2-user/.local/bin:/home/ec2-user/bin
Это подтверждено!
Как видите, после активации виртуальной среды первым каталогом в PATH становится каталог bin внутри виртуальной среды, которую мы создали и активировали.
Если мы хотим копнуть немного глубже, мы можем взглянуть на содержимое скрипта активации внутри /opt/blog/projects/codefathertech/bin /.
Следующие строки показывают, что делает скрипт активации. Он обновляет и экспортирует переменную среды PATH:
VIRTUAL_ENV='/opt/blog/projects/codefathertech'
export VIRTUAL_ENV
PATH="$VIRTUAL_ENV/bin:$PATH"
export PATH
Здесь вы можете узнать больше о том, как работает экспорт с переменными среды Linux.
А теперь давайте посмотрим, что делать, если мы хотим прекратить работу в виртуальной среде.
Деактивировать виртуальную среду
Точно так же, как вы активируете virtualenv, чтобы ограничить свои действия в этой среде, вы также можете его деактивировать.
Деактивация virtualenv возвращает вас в исходную среду, из которой вы пришли.
Вот пример…
(codefathertech) [ec2-user@host projects]$ deactivate
[ec2-user@host projects]$
Как вы можете видеть в левой части приглашения, перед запуском команды деактивации я нахожусь в virtualenv codefathertech.
После выполнения команды deactivate имя virtualenv исчезает из приглашения. Это означает, что мы больше не находимся в виртуальной среде.
Прежде чем перейти к следующему разделу, я хотел бы узнать, где находится команда deactivate. Я не увидел ее в структуре каталогов virtualenv, где присутствовал только скрипт activate.
Давайте посмотрим, сможем ли мы разгадать эту загадку!
Понятно, деактивация — это не команда…
…это функция, определенная в скрипте активации:
deactivate () {
unset -f pydoc >/dev/null 2>&1
# reset old environment variables
...
...
...
[full content of the function not included]
}
Полезно знать!
Установка модулей в Python Virtualenv
Итак, теперь, когда мы знаем, как устроена virtualenv, как ее активировать и как ее деактивировать. Следующий шаг —…
…понимание того, как новые пакеты устанавливаются в каталог lib, принадлежащий virtualenv, а не в системный каталог lib.
Причина аналогична той, что мы видели с бинарным файлом Python…
Каталог bin внутри виртуальной среды также содержит двоичный файл pip, который при запуске устанавливает пакеты внутри codefathertech/lib/python3.7/.
С момента активации virtualenv каждый пакет, который вы устанавливаете с помощью pip, попадет в виртуальную среду и не будет виден глобальной среде Python.
Удалить виртуальную среду Python
Удалить виртуальную среду очень просто. Вы можете просто удалить ее папку с помощью команды rm после деактивации виртуальной среды.
Например, в моей системе я бы выполнил следующие команды:
(codefathertech) [ec2-user@host projects]$ deactivate
[ec2-user@host projects]$ rm -fr codefathertech
Очень просто!
Заключение
Теперь вы знаете, что такое виртуальная среда Python и как она работает.
В этом руководстве мы увидели, как создать виртуальную среду, как активировать ее, чтобы начать использовать в одном из своих проектов, и как ее деактивировать.
Кроме того, мы также увидели:
- Как установить модули в virtualenv.
- Как Python сохраняет все автономным в этой виртуальной среде.
Имеет ли это для вас смысл? У вас есть вопросы?
Дайте мне знать в комментариях!