# 12. Виртуальные окружения и пакеты

## 12.1. Введение

Приложения Python часто используют пакеты и модули, не входящие в стандартную библиотеку. Иногда приложению необходима конкретная версия библиотеки, в которой устранена определенная ошибка, или же приложение написано с помощью устаревшей версии библиотечного интерфейса.

Это означает, что конкретная установка Python может быть непригодной одновременно для каждого приложения. Например, приложению А нужна версия 1.0 конкретного модуля, а приложению B нужна версия 2.0. Эти требования противоречат друг другу, и установка любой из версий 1.0 или 2.0 оставит одно из приложений не работоспособным.

Решением этой проблемы является создание виртуального окружения — автономного дерева каталогов, содержащего установку Python конкретной версии, а также набор дополнительных пакетов.

Разные приложения могут использовать разные виртуальные окружения. В примере с конфликтующими требованиями приложение А может использовать созданное для него виртуальное окружение с версией 1.0 нужного модуля, а приложение В исполняться в другом виртуальном окружении с версией 2.0 того же модуля. Если позднее приложению В потребуется обновить библиотеку до версии 3.0, то это никак не повлияет на виртуальное окружение приложения А.

## 12.2. Создание виртуального окружения

Модуль, используемый для создания и управления виртуальными окружениями, называется `venv`. `venv` установит ту версию Python, из которой была запущена команда (определяется опцией `--version`). Например, выполнение команды с помощью `python3.12` установит версию 3.12.

Чтобы создать виртуальное окружение, определитесь с каталогом, где оно должно находиться, и запустите модуль `venv` в виде скрипта, указав путь:

    python -m venv tutorial-env

Это создаст каталог `tutorial-env`, если он ещё не существует, а внутри — копию интерпретатора Python и необходимые служебные файлы.

Общепринятым расположением каталога для виртуального окружения является `.venv`. Это имя скрывает каталог в оболочке и не мешает работе, при этом объясняет его предназначение. Кроме того, оно не конфликтует с файлами `.env`, которые некоторые инструменты используют для переменных окружения.

После создания виртуального окружения его можно активировать.

В Windows запустите:

    tutorial-env\Scripts\activate

В Unix или MacOS выполните:

    source tutorial-env/bin/activate

(Этот скрипт расчитан на оболочку bash. Для оболочек csh или fish есть соответственно альтернативные файлы `activate.csh` и `activate.fish`, которые можно использовать).

Активация виртуального окружения изменит приглашение оболочки, показывая, какое окружение активно, и настроит его так, что команда `python` будет запускать именно эту установленную версию Python. Например:

    $ source ~/envs/tutorial-env/bin/activate
    (tutorial-env) $ python
    Python 3.5.1 (default, May  6 2016, 10:59:36)
      ...
    >>> import sys
    >>> sys.path
    ['', '/usr/local/lib/python35.zip', ...,
    '~/envs/tutorial-env/lib/python3.5/site-packages']
    >>>

Обратите внимание, что активированное виртуальное окружение никак не изменяет переменную `PYTHONPATH`. Это может привести к неожиданным результатам, если путь содержит ссылки на код, несовместимый с версией Python, используемой виртуальным окружением. В bash рекомендуется выполнить команду `unset PYTHONPATH` или её эквивалент для используемой вами оболочки.

Чтобы деактивировать виртуальное окружение, выполните:

    deactivate

в терминале.

## 12.3. Управление пакетами с помощью pip

Вы можете устанавливать, обновлять и удалять пакеты с помощью программы, называемой pip. По умолчанию `pip` будет устанавливать пакеты из Каталога пакетов Python. Вы можете просматривать его через web-браузер.

У `pip` есть несколько подкоманд: «install», «uninstall», «freeze» и т.д. (Подробную документацию по `pip` см. в руководстве Installing Python modules.)

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

    (tutorial-env) $ python -m pip install novas
    Collecting novas
      Downloading novas-3.1.1.3.tar.gz (136kB)
    Installing collected packages: novas
      Running setup.py install for novas
    Successfully installed novas-3.1.1.3

Для установки конкретной версии пакета укажите его имя и `==` с номером версии:

    (tutorial-env) $ python -m pip install requests==2.6.0
    Collecting requests==2.6.0
      Using cached requests-2.6.0-py2.py3-none-any.whl
    Installing collected packages: requests
    Successfully installed requests-2.6.0

Если вы повторно запустите эту команду, `pip` заметит, что запрошенная версия уже установлена и ничего не сделает. Вы можете указать другой номер версии, чтобы получить её, или можете запустить `python -m pip install --upgrade`, чтобы обновить пакет до последней версии.

    (tutorial-env) $ python -m pip install --upgrade requests
    Collecting requests
    Installing collected packages: requests
      Found existing installation: requests 2.6.0
        Uninstalling requests-2.6.0:
          Successfully uninstalled requests-2.6.0
    Successfully installed requests-2.7.0

Команда `python -m pip uninstall` с одним или несколькими именами пакетов удаляет их из виртуального окружения.

Команда `python -m pip show` выводит информацию о конкретном пакете:

    (tutorial-env) $ python -m pip show requests
    ---
    Metadata-Version: 2.0
    Name: requests
    Version: 2.7.0
    Summary: Python HTTP for Humans.
    Home-page: http://python-requests.org
    Author: Kenneth Reitz
    Author-email: me@kennethreitz.com
    License: Apache 2.0
    Location: /Users/akuchling/envs/tutorial-env/lib/python3.4/site-packages
    Requires:

Команда `python -m pip list` покажет все установленные в виртуальном окружении пакеты:

    (tutorial-env) $ python -m pip list
    novas (3.1.1.3)
    numpy (1.9.2)
    pip (7.0.3)
    requests (2.7.0)
    setuptools (16.0)

Команда `python -m pip freeze` выводит аналогичный список установленных пакетов, но в формате, который ожидает `python -m pip install`. Обычно этот список сохраняют в файл `requirements.txt`:

    (tutorial-env) $ python -m pip freeze > requirements.txt
    (tutorial-env) $ cat requirements.txt
    novas==3.1.1.3
    numpy==1.9.2
    requests==2.7.0

Файл `requirements.txt` можно сохранить в системе контроля версий и распространять вместе с приложением. После этого пользователи смогут установить все необходимые пакеты командой `install -r`:

    (tutorial-env) $ python -m pip install -r requirements.txt
    Collecting novas==3.1.1.3 (from -r requirements.txt (line 1))
      ...
    Collecting numpy==1.9.2 (from -r requirements.txt (line 2))
      ...
    Collecting requests==2.7.0 (from -r requirements.txt (line 3))
      ...
    Installing collected packages: novas, numpy, requests
      Running setup.py install for novas
    Successfully installed novas-3.1.1.3 numpy-1.9.2 requests-2.7.0

Инструмент `pip` имеет много других опций. Для полной документации по `pip` обратитесь к руководству Installing Python modules. Когда вы напишете собственный пакет и захотите разместить его в Каталоге пакетов Python, обратитесь к руководству пользователя по пакетированию в Python.