Виртуальные окружения и зависимости: замена 'просто скомпилировать с нужными флагами'
core создать и использовать виртуальное окружение для проекта, не смешивая зависимости с системным Python
В C версия каждой зависимости фиксируется явно: вы указываете конкретный .h/.so/.a, прописываете пути в Makefile или CMakeLists.txt, при необходимости статически линкуете нужную версию библиотеки внутрь бинарника. Конфликт версий решается на уровне сборки — вы физически выбираете, с чем линковаться.
В Python по умолчанию нет этого барьера: pip install requests кладёт пакет в site-packages того интерпретатора, который сейчас активен. Если это системный python3, то пакет становится виден всем проектам и скриптам на машине — это как если бы вы установили заголовок и .so прямо в /usr/include и /usr/lib без версионирования, и каждая программа в системе внезапно линковалась против одной и той же версии. Пока у вас один проект — это незаметно. Как только два проекта требуют разных версий одной библиотеки, система глобальных пакетов ломается, и никакой компилятор вам об этом не скажет — вы узнаете об этом в runtime, по ImportError или тихому неверному поведению.
Виртуальное окружение (virtual environment) — это отдельное окружение интерпретатора с собственным изолированным site-packages. Все установки пакетов внутри активного venv не затрагивают систему и другие проекты — ровно то же самое разделение, которое в C вы получаете через раздельные каталоги сборки и явные пути линковки, только автоматизированное.
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install requests==2.31
pip freeze > requirements.txt
Ключевая ошибка C-программиста здесь — интуиция «Python — это просто интерпретатор, зачем ему отдельная папка на каждый проект, это же не сборка бинарника». В C у вас есть один явный шаг компиляции, где решается, что с чем связано. В Python таким «шагом сборки» и является активация правильного venv перед запуском — если его нет, интерпретатор молча использует то, что первым нашёл в PATH, и это может быть не та версия зависимостей, которую вы тестировали.
Разобранный пример
Два проекта на одной машине: service-a требует requests==2.20, service-b — requests==2.31. Без изоляции:
pip install requests==2.20 # для service-a
pip install requests==2.31 # для service-b — тихо перезатёр первую версию
service-a теперь может ломаться на несовместимом API, и это выяснится не при сборке, а при выполнении конкретной ветки кода. С изоляцией:
cd service-a && python -m venv .venv && source .venv/bin/activate
pip install requests==2.20
cd ../service-b && python -m venv .venv && source .venv/bin/activate
pip install requests==2.31
Каждый проект носит свой «слинкованный набор библиотек» с собой, как если бы вы держали для каждого бинарника отдельный build/ со своими .so.
Попробуй сейчас
Создайте два каталога-проекта. В каждом — свой .venv, в первом установите requests==2.31, во втором вообще не устанавливайте requests. Не активируя ни один venv, попробуйте выполнить python -c "import requests" из системного python3. Затем сделайте то же самое, активировав каждый venv по очереди, и сравните результат pip list.
Ожидаемый результат: системный интерпретатор либо не видит requests вообще, либо видит не ту версию, что в проектных venv; каждый активированный venv показывает ровно свой набор пакетов, независимо от соседа.
Получилось, если…
Вы понимаете это, если можете объяснить коллеге: почему sudo pip install X в проектной работе — плохая практика (аналог «поставить хедер в системный include для всех сразу»), и почему requirements.txt — это не формальность, а способ воспроизвести окружение на другой машине без ручного угадывания версий.
graph TD
SP["Системный Python<br/>site-packages"] -->|"pip install без venv"| Conflict["Конфликт версий:<br/>одна версия requests на всех"]
subgraph ProjectA["service-a"]
VA["venv A<br/>requests==2.20"]
end
subgraph ProjectB["service-b"]
VB["venv B<br/>requests==2.31"]
end
SP -.->|"изолировано"| VA
SP -.->|"изолировано"| VBВывод
venv — это ваш личный, изолированный набор «слинкованных библиотек» на проект, а не бюрократическая надстройка. Не устанавливайте зависимости проекта в системный Python; всегда фиксируйте версии в requirements.txt (или pyproject.toml), как фиксировали бы версии библиотек в сборочном скрипте на C.
AI-generated · source-grounded review
🛡 Fact-checked: 1 risky claim verified · 3 removed · confidence: high · figures: 1
A second model re-checked this lesson's claims and corroborated 1 of 5 , and could not confirm 4 either way. This is incomplete corroboration, not a disagreement.
On your own course these buttons answer instantly, quizzes track what you've mastered, and lessons adapt to your gaps. Write my course