Python: Настройка окружения
Теория: Зависимости
Python, как и любой другой язык, содержит внутри себя много готовых функций и модулей, облегчающих разработку. Все вместе они составляют стандартную библиотеку языка. Например, модули для работы с криптографией (шифрование), HTTP, файловой системой и многие другие.
Какой бы хорошей ни была стандартная библиотека, она не может покрыть все задачи, возникающие во время разработки. Конечно, можно все недостающие компоненты реализовывать самостоятельно, но тогда разработка любого проекта превратится в бесконечный марафон. Слишком много типовых задач нужно решить в любом нетривиальном проекте.
В коммерческих проектах используются миллионы строк стороннего кода, написанные программистами по всему миру. Подобный код хранится в библиотеках, доступных для установки в проект. В Python-мире их принято называть пакетами.
Какие задачи решают подобные пакеты? Совершенно разные. От небольших полезных функций для работы со строками или датами, до фреймворков, программных систем, формирующих архитектуру кода. Например, библиотека more-itertools по типу стандартной библиотеки itertools. Она предоставляет около сотни полезных функций, решающих задачи по работе с массивами, строками и другими типами данных. Пара примеров:
Каждая из этих функций по отдельности может выглядеть небольшой. Однако чем больше проект, тем больше требуется подобных функций, и все вместе они превращаются в довольно большую кодовую базу. А ведь еще хотелось бы иметь хорошую документацию.
Обратите внимание на то, как происходит импорт кода. Мы указываем лишь нужные нам функции из библиотеки, чтобы не загружать ее всю. В случае объемных библиотек с сотнями функций такой подход предпочтительнее.
Установка
Если просто импортировать more-itertools в коде и затем запустить код на выполнение, то программа упадет с ошибкой: "more-itertools не найден". Для того чтобы воспользоваться сторонним пакетом, его нужно добавить в проект как зависимость. Так говорят потому, что код проекта теперь зависит от этих библиотек. Для этого в uv предусмотрена команда установки:
Эта команда выполняет три действия. Сначала она скачивает пакет из репозитория пакетов в директорию .venv в корне проекта. Если этой директории не было, то она автоматически создается. Затем она добавляет запись в pyproject.toml о том, что пакет more-itertools стал зависимостью. И наконец, создает или обновляет файл uv.lock.
Зависимости в pyproject.toml добавляются под ключом dependencies. Здесь указаны все пакеты, используемые в проекте и не входящие в стандартную библиотеку.
В качестве ключа в зависимостях указывается имя пакета. Именно это имя используется при импорте пакета. Значением является последняя доступная версия на момент скачивания.
Также мы можем посмотреть все дерево зависимостей командой uv tree
На деле устройство директории .venv несколько сложнее, и об этом будет позже, но главное, что это директория, в которой хранятся все скачанные пакеты для нашего проекта.
Осталось разобраться с файлом uv.lock. Детально о нем будет позже в курсе, а сейчас опишем его общую концепцию.
Если кратко, то у зависимостей нашего проекта есть свои зависимости, такие же сторонние библиотеки, которые разработчики использовали для написания своих библиотек. А у них, в свою очередь, свои зависимости (зависимости зависимостей называются транзитивными зависимостями). Подобная цепочка может быть довольно длинной и на разных ее участках возможно появление одних и тех же пакетов, но разных версий. uv.lock содержит описание всех пакетов, которые будут поставлены, включая все их зависимости с указанием конкретных версий. Это позволяет получать гарантированно одни и те же версии зависимостей для всех разработчиков проекта. Этот файл, его называют lock-файл, используется для синхронизации зависимостей.
Связь с GIT
Программисты не так часто делают проекты "с нуля". Чаще всего они работают с готовыми проектами. Проекты же, в свою очередь, хранятся в git-репозиториях. Что нужно хранить в репозитории, а что нет, когда мы говорим о зависимостях?
Код самих зависимостей не является частью исходного кода. Потому директорию .venv всегда добавляют в .gitignore. А вот файлы pyproject.toml и uv.lock являются важной частью исходного кода. Именно через них пакетный менеджер узнает о том, какие пакеты нужно поставить в систему.
Представьте, что вы клонируете готовый проект с GitHub на свой компьютер и сразу пробуете запустить. Он упадет с ошибкой, так как сами зависимости еще не скачаны в .venv, и сама директория отсутствует. Чтобы они появились, нужно запустить команду установки зависимостей из lock-файла проекта и файла описания проекта:
Эта команда скачивает зависимости в директорию .venv, базируясь на содержимом pyproject.toml и версиях из uv.lock.
Обновление и удаление зависимостей
Помимо добавления зависимостей uv позволяет также обновлять текущие, указанные в pyproject.toml
Эта команда удалит устаревшие зависимости, скачает новые и пересоздаст lock-файл.
Теперь попробуем удалить ненужную нам зависимость из проекта.
Команда удалит зависимость и обновит lock-файл после.



