Virtualenv
Есть куча способов установки питоновских пакетов. Какие-то более удобны, какие-то менее, в зависимости от ситуации. Опишу способ, который мне оказался удобен в большинстве случаев.
Для его использования не нужно ничего, кроме собственно virtualenv и pip. Для каждого проекта я использую отдельную среду со своим набором пакетов - мне так удобнее управлять зависимостями.
Для создания окружений я использую небольшую функцию в ~/.profile:
mkenv() {
VENV_PATH="$HOME/.python-envs`pwd`"
virtualenv --no-site-packages -p `which python` $VENV_PATH
echo "VIRTUALENV_PATH=$VENV_PATH" > .venv
source $VENV_PATH/bin/activate
}
Окружения создаются в скрытой папке ~/.python-envs/<путь_к_папке_с_проектом>, а путь к окружению пишется в папку проекта в скрытый файл .venv. В принципе, путь можно и вычислять, но я уже пару раз менял место для новых окружений, а так нет необходимости переносить старые.
Далее, хотелось бы как-то автоматически активировать окружение, когда мы начинаем работать с проектом. Для этой цели я использую еще один скрипт, лежащий в ~/.profile и проверяющий как раз файлы .venv. Скрипт срабатывает, когда изменилась текущая директория.
PREVPWD=`pwd`
PREVENV_PATH=
PREV_PS1=
PREV_PATH=
handle_virtualenv(){
if [ "$PWD" != "$PREVPWD" ]; then
PREVPWD="$PWD";
if [ -n "$PREVENV_PATH" ]; then
if [ "`echo "$PWD" | grep -c $PREVENV_PATH`" = "0" ]; then
source $PREVENV_PATH/.venv
echo "> Virtualenv `basename $VIRTUALENV_PATH` deactivated"
PS1=$PREV_PS1
PATH=$PREV_PATH
PREVENV_PATH=
fi
fi
if [ -e "$PWD/.venv" ] && [ "$PWD" != "$PREVENV_PATH" ]; then
PREV_PS1="$PS1"
PREV_PATH="$PATH"
PREVENV_PATH="$PWD"
source $PWD/.venv
echo $VIRTUALENV_PATH
source $VIRTUALENV_PATH/bin/activate
echo "> Virtualenv `basename $VIRTUALENV_PATH` activated"
fi
fi
}
export PROMPT_COMMAND=handle_virtualenv
Вот собственно и всё. Какие это даёт удобства:
- не надо ставить еще что-то, например virtualenvwrapper
- легко отслеживать зависимости с помощью pip, легко увидеть набор пакетов, нужных конкретному проекту
- окружения включаются и выключаются автоматически тогда, когда они нужны
Чтобы не тянуть пакеты из сети каждый раз, когда они нужны, а также на случай падения pypi или атомной войны, можно еще добавить сюда использование PIP_DOWNLOAD_CACHE и collective.eggproxy.