Перейти к содержанию

Виртуальные окружения

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

Дополнительная информация

Если вы уже знакомы с виртуальными окружениями, знаете, как их создавать и использовать, вы можете пропустить этот раздел. 🤓

Подсказка

Виртуальное окружение — это не то же самое, что переменная окружения.

Переменная окружения — это переменная в системе, которую могут использовать программы.

Виртуальное окружение — это директория с файлами внутри.

Дополнительная информация

На этой странице вы узнаете, как пользоваться виртуальными окружениями и как они работают.

Если вы готовы начать использовать инструмент, который управляет всем за вас (включая установку Python), попробуйте uv.

Создание проекта

Сначала создайте директорию для вашего проекта.

Обычно я создаю папку с именем code в моем домашнем каталоге.

А внутри неё создаю отдельную директорию для каждого проекта.

// Перейдите в домашний каталог
$ cd
// Создайте директорию для всех ваших проектов с кодом
$ mkdir code
// Перейдите в эту директорию code
$ cd code
// Создайте директорию для этого проекта
$ mkdir awesome-project
// Перейдите в директорию проекта
$ cd awesome-project

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

Когда вы начинаете работать над Python‑проектом впервые, создайте виртуальное окружение внутри вашего проекта.

Подсказка

Делать это нужно один раз на проект, не каждый раз, когда вы работаете.

Для создания виртуального окружения вы можете использовать модуль venv, который поставляется вместе с Python.

$ python -m venv .venv
Что делает эта команда?
  • python: использовать программу под названием python
  • -m: вызвать модуль как скрипт, далее мы укажем, какой модуль вызвать
  • venv: использовать модуль venv, который обычно устанавливается вместе с Python
  • .venv: создать виртуальное окружение в новой директории .venv

Если у вас установлен uv, вы можете использовать его для создания виртуального окружения.

$ uv venv

Подсказка

По умолчанию uv создаст виртуальное окружение в директории с именем .venv.

Но вы можете переопределить это, передав дополнительный аргумент с именем директории.

Эта команда создаст новое виртуальное окружение в директории .venv.

.venv или другое имя?

Вы можете создать виртуальное окружение в другой директории, но по соглашению его называют .venv.

Активация виртуального окружения

Активируйте новое виртуальное окружение, чтобы все команды Python и устанавливаемые пакеты использовали именно его.

Подсказка

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

$ source .venv/bin/activate
$ .venv\Scripts\Activate.ps1

Или если вы используете Bash для Windows (например, Git Bash):

$ source .venv/Scripts/activate

Подсказка

Каждый раз, когда вы устанавливаете новый пакет в это окружение, активируйте окружение снова.

Это гарантирует, что если вы используете программу терминала (CLI), установленную этим пакетом, вы будете использовать именно ту, что из вашего виртуального окружения, а не какую‑то глобально установленную, возможно другой версии, чем вам нужна.

Проверка, что виртуальное окружение активно

Проверьте, что виртуальное окружение активно (предыдущая команда сработала).

Подсказка

Это необязательно, но это хороший способ проверить, что всё работает как ожидается и вы используете запланированное виртуальное окружение.

$ which python

/home/user/code/awesome-project/.venv/bin/python

Если отображается исполняемый файл python по пути .venv/bin/python внутри вашего проекта (в нашем случае awesome-project), значит всё сработало. 🎉

$ Get-Command python

C:\Users\user\code\awesome-project\.venv\Scripts\python

Если отображается исполняемый файл python по пути .venv\Scripts\python внутри вашего проекта (в нашем случае awesome-project), значит всё сработало. 🎉

Обновление pip

Подсказка

Если вы используете uv, то для установки вы будете использовать его вместо pip, поэтому обновлять pip не нужно. 😎

Если для установки пакетов вы используете pip (он идёт по умолчанию вместе с Python), вам стоит обновить его до последней версии.

Многие экзотические ошибки при установке пакетов решаются простым предварительным обновлением pip.

Подсказка

Обычно это делается один раз, сразу после создания виртуального окружения.

Убедитесь, что виртуальное окружение активно (см. команду выше) и запустите:

$ python -m pip install --upgrade pip

---> 100%

Добавление .gitignore

Если вы используете Git (а вам стоит его использовать), добавьте файл .gitignore, чтобы исключить из Git всё, что находится в вашей .venv.

Подсказка

Если вы использовали uv для создания виртуального окружения, он уже сделал это за вас — можно пропустить этот шаг. 😎

Подсказка

Сделайте это один раз, сразу после создания виртуального окружения.

$ echo "*" > .venv/.gitignore
Что делает эта команда?
  • echo "*": «напечатать» в терминале текст * (следующая часть немного меняет поведение)
  • >: всё, что команда слева от > выводит в терминал, вместо печати нужно записать в файл, указанный справа от >
  • .gitignore: имя файла, в который нужно записать текст

А * в Git означает «всё». То есть будет игнорироваться всё в директории .venv.

Эта команда создаст файл .gitignore со следующим содержимым:

*

Установка пакетов

После активации окружения вы можете устанавливать в него пакеты.

Подсказка

Сделайте это один раз при установке или обновлении пакетов, необходимых вашему проекту.

Если вам нужно обновить версию или добавить новый пакет, вы сделаете это снова.

Установка пакетов напрямую

Если вы торопитесь и не хотите объявлять зависимости проекта в отдельном файле, вы можете установить их напрямую.

Подсказка

Очень хорошая идея — указать используемые вашим проектом пакеты и их версии в файле (например, requirements.txt или pyproject.toml).

$ pip install "fastapi[standard]"

---> 100%

Если у вас установлен uv:

$ uv pip install "fastapi[standard]"
---> 100%

Установка из requirements.txt

Если у вас есть requirements.txt, вы можете использовать его для установки пакетов.

$ pip install -r requirements.txt
---> 100%

Если у вас установлен uv:

$ uv pip install -r requirements.txt
---> 100%
requirements.txt

requirements.txt с некоторыми пакетами может выглядеть так:

fastapi[standard]==0.113.0
pydantic==2.8.0

Запуск вашей программы

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

$ python main.py

Hello World

Настройка вашего редактора кода

Скорее всего, вы будете использовать редактор кода. Убедитесь, что вы настроили его на использование того же виртуального окружения, которое вы создали (обычно он определяет его автоматически), чтобы получить автозавершение и подсветку ошибок.

Например:

Подсказка

Обычно это нужно сделать только один раз, при создании виртуального окружения.

Деактивация виртуального окружения

Когда закончите работу над проектом, вы можете деактивировать виртуальное окружение.

$ deactivate

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

Готово к работе

Теперь вы готовы начать работать над своим проектом.

Подсказка

Хотите понять, что это всё было выше?

Продолжайте читать. 👇🤓

Зачем нужны виртуальные окружения

Чтобы работать с FastAPI, вам нужно установить Python.

После этого вам нужно будет установить FastAPI и другие пакеты, которые вы хотите использовать.

Для установки пакетов обычно используют команду pip, которая идет вместе с Python (или альтернативные инструменты).

Тем не менее, если просто использовать pip напрямую, пакеты будут установлены в глобальное окружение Python (глобально установленный Python).

Проблема

Так в чём проблема установки пакетов в глобальное окружение Python?

Со временем вы, вероятно, будете писать много разных программ, зависящих от разных пакетов. И некоторые из ваших проектов будут зависеть от разных версий одного и того же пакета. 😱

Например, вы можете создать проект philosophers-stone, который зависит от пакета harry версии 1. Значит, нужно установить harry.

flowchart LR
    stone(philosophers-stone) -->|requires| harry-1[harry v1]

Затем вы создаёте другой проект prisoner-of-azkaban, который тоже зависит от harry, но ему нужен harry версии 3.

flowchart LR
    azkaban(prisoner-of-azkaban) --> |requires| harry-3[harry v3]

Проблема в том, что если устанавливать пакеты глобально (в глобальное окружение), а не в локальное виртуальное окружение, вам придётся выбирать, какую версию harry установить.

Если вы хотите запустить philosophers-stone, сначала нужно установить harry версии 1, например так:

$ pip install "harry==1"

Тогда у вас в глобальном окружении Python будет установлен harry версии 1:

flowchart LR
    subgraph global[global env]
        harry-1[harry v1]
    end
    subgraph stone-project[philosophers-stone project]
        stone(philosophers-stone) -->|requires| harry-1
    end

Но если затем вы захотите запустить prisoner-of-azkaban, вам нужно будет удалить harry версии 1 и установить harry версии 3 (или просто установка версии 3 автоматически удалит версию 1).

$ pip install "harry==3"

В итоге у вас будет установлен harry версии 3 в глобальном окружении Python.

А если вы снова попробуете запустить philosophers-stone, есть шанс, что он не будет работать, так как ему нужен harry версии 1.

flowchart LR
    subgraph global[global env]
        harry-1[<strike>harry v1</strike>]
        style harry-1 fill:#ccc,stroke-dasharray: 5 5
        harry-3[harry v3]
    end
    subgraph stone-project[philosophers-stone project]
        stone(philosophers-stone) -.-x|⛔️| harry-1
    end
    subgraph azkaban-project[prisoner-of-azkaban project]
        azkaban(prisoner-of-azkaban) --> |requires| harry-3
    end

Подсказка

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

Теперь представьте то же самое с многими другими пакетами, от которых зависят все ваши проекты. Этим очень сложно управлять. И вы, скорее всего, в какой‑то момент будете запускать проекты с несовместимыми версиями пакетов и не понимать, почему что‑то не работает.

Кроме того, в зависимости от ОС (например, Linux, Windows, macOS), она может поставляться с уже установленным Python. И тогда, вероятно, в системе уже есть предустановленные пакеты определённых версий, нужные вашей системе. Если вы устанавливаете пакеты в глобальное окружение Python, вы можете в итоге сломать некоторые системные программы.

Куда устанавливаются пакеты

Когда вы устанавливаете Python, на вашем компьютере создаются некоторые директории с файлами.

Часть этих директорий отвечает за хранение всех устанавливаемых вами пакетов.

Когда вы запускаете:

// Не запускайте это сейчас, это просто пример 🤓
$ pip install "fastapi[standard]"
---> 100%

Будет загружен сжатый файл с кодом FastAPI, обычно с PyPI.

Также будут загружены файлы для других пакетов, от которых зависит FastAPI.

Затем все эти файлы будут распакованы и помещены в директорию на вашем компьютере.

По умолчанию они попадут в директорию из вашей установки Python — это глобальное окружение.

Что такое виртуальные окружения

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

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

Таким образом, у каждого проекта будет своё виртуальное окружение (директория .venv) со своими пакетами.

flowchart TB
    subgraph stone-project[philosophers-stone project]
        stone(philosophers-stone) --->|requires| harry-1
        subgraph venv1[.venv]
            harry-1[harry v1]
        end
    end
    subgraph azkaban-project[prisoner-of-azkaban project]
        azkaban(prisoner-of-azkaban) --->|requires| harry-3
        subgraph venv2[.venv]
            harry-3[harry v3]
        end
    end
    stone-project ~~~ azkaban-project

Что означает активация виртуального окружения

Когда вы активируете виртуальное окружение, например так:

$ source .venv/bin/activate
$ .venv\Scripts\Activate.ps1

Или если вы используете Bash для Windows (например, Git Bash):

$ source .venv/Scripts/activate

Эта команда создаст или изменит некоторые переменные окружения, которые будут доступны для следующих команд.

Одна из таких переменных — PATH.

Подсказка

Вы можете узнать больше о переменной окружения PATH в разделе Переменные окружения.

Активация виртуального окружения добавляет его путь .venv/bin (на Linux и macOS) или .venv\Scripts (на Windows) в переменную окружения PATH.

Предположим, что до активации окружения переменная PATH выглядела так:

/usr/bin:/bin:/usr/sbin:/sbin

Это означает, что система будет искать программы в:

  • /usr/bin
  • /bin
  • /usr/sbin
  • /sbin
C:\Windows\System32

Это означает, что система будет искать программы в:

  • C:\Windows\System32

После активации виртуального окружения переменная PATH будет выглядеть примерно так:

/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin

Это означает, что теперь система в первую очередь будет искать программы в:

/home/user/code/awesome-project/.venv/bin

прежде чем искать в других директориях.

Поэтому, когда вы введёте в терминале python, система найдёт программу Python по пути

/home/user/code/awesome-project/.venv/bin/python

и использует именно её.

C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32

Это означает, что теперь система в первую очередь будет искать программы в:

C:\Users\user\code\awesome-project\.venv\Scripts

прежде чем искать в других директориях.

Поэтому, когда вы введёте в терминале python, система найдёт программу Python по пути

C:\Users\user\code\awesome-project\.venv\Scripts\python

и использует именно её.

Важная деталь: путь к виртуальному окружению будет добавлен в самое начало переменной PATH. Система найдёт его раньше, чем любой другой установленный Python. Таким образом, при запуске python будет использоваться Python из виртуального окружения, а не какой‑то другой python (например, из глобального окружения).

Активация виртуального окружения также меняет ещё несколько вещей, но это — одна из важнейших.

Проверка виртуального окружения

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

$ which python

/home/user/code/awesome-project/.venv/bin/python
$ Get-Command python

C:\Users\user\code\awesome-project\.venv\Scripts\python

Это означает, что будет использоваться программа python из виртуального окружения.

На Linux и macOS используется which, а в Windows PowerShell — Get-Command.

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

Самое важное — при вызове python именно этот «python» и будет выполняться.

Так вы можете подтвердить, что находитесь в правильном виртуальном окружении.

Подсказка

Легко активировать одно виртуальное окружение, получить один Python, а затем перейти к другому проекту.

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

Полезно уметь проверить, какой именно python используется. 🤓

Зачем деактивировать виртуальное окружение

Например, вы работаете над проектом philosophers-stone, активируете виртуальное окружение, устанавливаете пакеты и работаете с ним.

Затем вы хотите поработать над другим проектом prisoner-of-azkaban.

Вы переходите в этот проект:

$ cd ~/code/prisoner-of-azkaban

Если вы не деактивируете виртуальное окружение philosophers-stone, при запуске python в терминале он попытается использовать Python из philosophers-stone.

$ cd ~/code/prisoner-of-azkaban

$ python main.py

// Error importing sirius, it's not installed 😱
Traceback (most recent call last):
    File "main.py", line 1, in <module>
        import sirius

Но если вы деактивируете виртуальное окружение и активируете новое для prisoner-of-askaban, тогда при запуске python он будет использовать Python из виртуального окружения prisoner-of-azkaban.

$ cd ~/code/prisoner-of-azkaban

// Вам не нужно находиться в старой директории, чтобы деактивировать окружение, вы можете сделать это где угодно, даже после перехода в другой проект 😎
$ deactivate

// Активируйте виртуальное окружение в prisoner-of-azkaban/.venv 🚀
$ source .venv/bin/activate

// Теперь при запуске python он найдёт пакет sirius, установленный в этом виртуальном окружении ✨
$ python main.py

I solemnly swear 🐺

Альтернативы

Это простое руководство, чтобы вы начали и поняли, как всё работает под капотом.

Существует много альтернатив для управления виртуальными окружениями, зависимостями (requirements), проектами.

Когда вы будете готовы и захотите использовать инструмент для управления всем проектом — зависимостями пакетов, виртуальными окружениями и т. п., я бы предложил попробовать uv.

uv может многое:

  • Устанавливать Python, включая разные версии
  • Управлять виртуальным окружением ваших проектов
  • Устанавливать пакеты
  • Управлять зависимостями и версиями пакетов вашего проекта
  • Обеспечивать наличие точного набора пакетов и версий к установке, включая их зависимости, чтобы вы были уверены, что сможете запускать проект в продакшне точно так же, как и на компьютере при разработке — это называется locking
  • И многое другое

Заключение

Если вы прочитали и поняли всё это, теперь вы знаете гораздо больше о виртуальных окружениях, чем многие разработчики. 🤓

Знание этих деталей, скорее всего, пригодится вам в будущем, когда вы будете отлаживать что‑то сложное: вы будете понимать, как всё работает под капотом. 😎