Вступление
Как разработчики Python, большинство из нас знакомы с виртуальными средами . Первое, что мы делаем при работе над новым проектом, - это создаем среду. Обычно мы используем virtualenv или venv именно для этой цели.
Каждый проект, над которым мы работаем, использует разные пакеты и может даже быть совместим только с одной версией Python.
Постоянное выполнение чего-либо требует автоматизации. В этой статье мы
увидим, как direnv
и pyenv
могут помочь нам в этом.
Кстати, некоторые современные IDE уже автоматизировали эти шаги. Например, PyCharm создаст виртуальную среду при инициализации проекта:
{.ezlazyload}
Хотя автоматизация всех этих шагов является большим выигрышем, если мы используем IDE, которые поддерживают такие функции, более общее решение должно быть независимым от IDE.
Проблемы virtualenv
Представьте, что мы нашли проект на GitHub и хотели бы поиграть с ним. Pyweather - это простой скрипт, который запрашивает расширенный прогноз погоды для нашего местоположения и распечатывает его на терминале.
Вот шаги, которые мы предпринимаем, чтобы опробовать скрипт на нашей машине:
$ git clone https://github.com/lcofre/pyweather.git
$ cd pyweather
Затем мы создаем виртуальную среду и устанавливаем пакеты, которые использует скрипт:
$ virtualenv --python=python3 env
$ source env/bin/activate
(env) $ pip install requirements.txt
И только тогда мы можем выполнить скрипт:
(env) $ ./pyweather.py
Мы создали виртуальную среду и сохранили ее в корневой папке нашего
проекта. Находясь в этой папке, нам пришлось активировать среду с
помощью source
команды.
Когда мы закончим работу, нам нужно покинуть виртуальную среду, выполнив
deactivate
:
(env) $ deactivate
Все эти шаги - наша ответственность. Сколько раз мы могли забыть активировать среду и установить пакет глобально!
Посмотрим, как direnv
помогает нам это автоматизировать.
Direnv
direnv
был создан в
основном для загрузки переменных среды в зависимости от текущего
каталога и имеет расширение для многих оболочек.
В этом примере мы будем использовать bash
, но direnv
поддерживает
многие другие оболочки. И что более важно для нас, это позволяет нам
управлять виртуальными средами Python.
Чтобы установить его, мы запустим bash
они предоставляют. Мы могли бы
использовать диспетчер пакетов нашего дистрибутива, но bash
обеспечит
установку последней доступной версии:
$ curl -sfL https://direnv.net/install.sh | bash
Теперь нам нужно подключить direnv
к bash
. Мы отредактируем
~/.bashrc
а затем перезагрузим его:
$ echo 'eval "$(direnv hook bash)"' >> ~/.bashrc
$ source ~/.bashrc
Таким образом, direnv
свяжется с оболочкой и будет выполняться всегда
перед каждым запросом. Мы никогда не заметим, что он работает на заднем
плане.
direnv
проверит, нужно ли что-то загрузить в текущую папку. Он
проверяет наличие файла с именем .envrc
с инструкциями о том, что
следует загрузить.
Чтобы загрузить виртуальные среды Python, мы запускаем команду layout
, за которой следует версия Python:
$ echo 'layout python' > .envrc
Или, если мы хотим использовать Python 3:
$ echo 'layout python3' > .envrc
direnv
искать python
или python3
на пути.
Как только мы создадим .envrc
нас предупредят, что нам нужно разрешить
direnv
доступ к этой папке. Сделаем это прямо сейчас:
$ direnv allow
direnv: loading .envrc
...
New python executable in /home/myuser/untitled/.direnv/python-3.6.9/bin/python3
...
Installing setuptools, pkg_resources, pip, wheel...direnv:
done.
direnv: export +VIRTUAL_ENV ~PATH
Как видно из выходных данных, виртуальная среда была создана немедленно. Однако приглашение не изменяется, поэтому мы не увидим имя среды, написанное в начале.
Теперь мы можем установить нужные нам пакеты, как мы это делали в среде, созданной в предыдущем разделе:
$ pip install -r requirements.txt
direnv
незаметно активирует окружение в фоновом режиме. Каждый раз,
когда мы выходим из каталога, среда отключается:
$ cd ..
direnv: unloading
Если мы можем использовать любую версию Python, установленную в системе,
direnv
- это все, что нам нужно.
Предположим теперь, что нашему pyweather
требуется очень специфическая
версия.
Pyenv
pyenv
- это утилита
управления версиями для Python. Он позволяет, среди прочего, изменять
версии Python для каждого проекта. direnv
поддерживает его, начиная с
версии 2.21.0
, поэтому вместе они могут дать нам более высокий
уровень контроля над версией, которую мы используем в нашей среде.
Начнем с установки pyenv
:
$ curl -L https://pyenv.run | bash
А затем убедитесь, что он всегда будет доступен для нашего терминала:
$ echo 'export PATH="~/.pyenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
$ echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
$ source ~/.bashrc
Теперь предположим, что нашему pyweather
требуется очень специфическая
версия Python, 3.6.2
.
Во-первых, нам нужно установить эту версию Python:
$ pyenv install 3.6.2
И теперь мы можем настроить наш проект для использования конкретной версии:
$ echo 'layout pyenv 3.6.2' > .envrc
$ direnv allow
Мы можем подтвердить, что все работает должным образом, проверив версию Python в среде:
$ python --version
Python 3.6.2
Если нам когда-нибудь понадобится изменить версию Python, нам будет
достаточно изменить макет в файле .envrc
Благодаря обеим утилитам мы можем изменить макет на любую версию Python, и наша виртуальная среда будет обновлена сразу.
Еще одно преимущество использования direnv
и pyenv
заключается в
том, что мы можем .envrc
версию нашего файла .envrc в нашем
репозитории проекта.
Таким образом, все участники смогут настроить свою среду так, как задумано проектом, при условии, что они установят необходимые утилиты и версию Python.
Заключение
Виртуальные среды в некотором роде отделены от рабочего процесса
разработки Python. Нам нужно не забыть настроить и активировать его
перед работой с нашим проектом. Благодаря direnv
и pyenv
мы можем
автоматизировать все это, а вход в папку проекта сделает всю работу за
нас в фоновом режиме.
Установить обе утилиты непросто, но после того, как они будут выполнены один раз, мы сэкономим много времени. У нас также всегда будет уверенность в том, что мы работаем с правильной виртуальной средой и версией Python.