Виртуальные окружения: venv и изоляция зависимостей
Виртуальные окружения: venv и изоляция зависимостей
В прошлом уроке мы запускали скрипты на чистом Python без сторонних библиотек. В реальных проектах сторонних пакетов десятки: FastAPI, Pydantic, SQLAlchemy, pytest, requests. Если ставить их прямо в системный Python - быстро возникает каша версий, и проекты ломают друг друга. Решение - виртуальные окружения.
Проблема общего Python
Представь две задачи на одной машине:
- Проект A использует
pydantic==1.10(старый legacy) - Проект B использует
pydantic==2.6(новый, не совместим по API)
Если оба ставят зависимости в один и тот же python3, второй pip install pydantic==2.6 перезапишет первый, и проект A сломается. Это типичная проблема dependency hell.
Виртуальное окружение - отдельная директория с собственным интерпретатором и набором пакетов, изолированная от системы и других проектов.
Создаём venv
Стандартный инструмент - модуль venv из стандартной библиотеки. Он не требует установки.
# В корне проекта
python3 -m venv .venv
Команда создаёт директорию .venv/ со структурой:
bin/(на Windows -Scripts/) - исполняемые файлы окружения: симлинк на интерпретатор,pipдля установки пакетов,activateдля активацииlib/- сюдаpip installкладёт пакеты, изолированно от системного Pythonpyvenv.cfg- конфигурация: на какой базовый Python ссылается окружение, version, флаги
Активация и деактивация
После создания окружение нужно активировать в текущем терминале:
source .venv/bin/activate
source .venv/bin/activate
.venv\Scripts\Activate.ps1
В cmd:
.venv\Scripts\activate.bat
После активации в приглашении терминала появится префикс (.venv). Это значит что python и pip теперь указывают на исполняемые файлы внутри окружения:
(.venv) $ which python
/path/to/project/.venv/bin/python
(.venv) $ which pip
/path/to/project/.venv/bin/pip
Для выхода:
deactivate
Ставим первый пакет
С активным venv установка не загрязняет систему:
(.venv) $ pip install requests
Collecting requests
Downloading requests-2.31.0-py3-none-any.whl
Installing collected packages: requests
Successfully installed requests-2.31.0
Проверь:
(.venv) $ pip list
Package Version
---------- -------
pip 23.x.x
requests 2.31.0
setuptools 65.x.x
Используем в коде:
import requests
response = requests.get("https://api.github.com/zen")
print(response.text)
Запускаем python script.py - всё работает. Деактивируешь окружение и запускаешь тот же скрипт системным python - получишь ModuleNotFoundError. Это и есть изоляция.
Фиксируем зависимости: requirements.txt
Чтобы другой разработчик (или CI, или продакшн) повторил окружение, нужно зафиксировать список пакетов:
(.venv) $ pip freeze > requirements.txt
Файл выглядит так:
certifi==2024.2.2
charset-normalizer==3.3.2
idna==3.6
requests==2.31.0
urllib3==2.2.0
Все транзитивные зависимости явно зафиксированы. Это и плюс (полная воспроизводимость), и минус (requirements.txt шумный).
Восстановить окружение по файлу:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Файл .gitignore
В каждый Python-проект сразу добавляй базовый .gitignore:
# Виртуальное окружение
.venv/
venv/
# Кеш интерпретатора
__pycache__/
*.pyc
*.pyo
# Файлы IDE
.idea/
.vscode/
# Переменные окружения
.env
# Артефакты сборки
dist/
build/
*.egg-info/
Без него легко закоммитить .venv/ весом в сотни мегабайт, что испортит репозиторий и потребует чистки истории.
Распространённые ошибки
Ошибка 1: ставить пакеты в системный Python. Если ты вызвал pip install something без активного venv - пакет улёгся в системный Python. На некоторых системах это даже требует sudo, что вообще ломает права. Решение - всегда работать в venv.
Ошибка 2: коммитить .venv/. Окружение - артефакт сборки, оно платформо-зависимое (Linux-окружение не запустится на Windows). Коммитят только requirements.txt или pyproject.toml.
Ошибка 3: забыть активировать venv. Запускаешь python script.py без активации - используется системный интерпретатор, ничего не находит. Проверка: which python (Linux/macOS) или where python (Windows) - путь должен указывать в .venv/.
Ошибка 4: использовать pip3 после активации. После активации pip уже указывает на исполняемый файл внутри venv. Писать pip3 не нужно, обычный pip работает корректно. Это путает: некоторые гайды показывают pip3 для системного Python.
Альтернативы venv
В экосистеме есть несколько менеджеров окружений и зависимостей:
| Инструмент | Что делает |
|---|---|
| venv | Стандартный, минималистичный. Только окружения. |
| virtualenv | Старый аналог venv, теперь почти не нужен (venv достаточен) |
| conda | Окружения + бинарные пакеты (для data science, не для backend) |
| pyenv | Установка нескольких версий Python (управление интерпретаторами, не пакетами) |
| poetry | Современный: окружение + зависимости + сборка + публикация |
| uv | Новый быстрый менеджер от Astral, drop-in замена pip/venv |
Для backend-разработки в 2026 году лучший выбор - venv + poetry или uv. Базовый venv нужно знать в любом случае - на нём построены все остальные инструменты.
Мини-задание
- В новой пустой директории создай venv и активируй его:
mkdir myproject && cd myproject
python3 -m venv .venv
source .venv/bin/activate
- Проверь куда указывает
python:
which python
which pip
- Установи библиотеку
requests, напиши скриптfetch.py:
import requests
print(requests.get("https://api.github.com/zen").text)
Запусти и убедись что выводится цитата.
-
Зафиксируй зависимости:
pip freeze > requirements.txt. Открой файл - убедись что requests и его транзитивные зависимости в списке. -
Деактивируй (
deactivate), удали.venv/, восстанови окружение изrequirements.txt. Убедись что скрипт по-прежнему работает.
Что дальше
Поняли как изолировать окружение и фиксировать зависимости. Тот же .venv будет нужен, когда дойдём до запуска тестов через pytest. В следующем уроке углубимся в pip и pyproject.toml: чем отличается pip install от добавления зависимости в файл, и почему всё больше проектов отказываются от requirements.txt в пользу декларативного pyproject.toml.