Python, как и любой другой язык, содержит внутри себя много готовых функций и модулей, облегчающих разработку. Все вместе они составляют стандартную библиотеку языка. Например, модули для работы с криптографией (шифрование), HTTP, файловой системой и многие другие.
# Пример встроенной функции
sum([1, 2, 3]) # 6
# Встроенный модуль для работы с файлами
import os
# Читает содержимое файла
data = os.open("path/to/file").read()
Какой бы хорошей ни была стандартная библиотека, она не может покрыть все задачи, возникающие во время разработки. Конечно, можно все недостающие компоненты реализовывать самостоятельно, но тогда разработка любого проекта превратится в бесконечный марафон. Слишком много типовых задач нужно решить в любом нетривиальном проекте.
В коммерческих проектах используются миллионы строк стороннего кода, написанные программистами по всему миру. Подобный код хранится в библиотеках, доступных для установки в проект. В Python-мире их принято называть пакетами.
Какие задачи решают подобные пакеты? Совершенно разные. От небольших полезных функций для работы со строками или датами, до фреймворков, программных систем, формирующих архитектуру кода. Например, библиотека more-itertools по типу стандартной библиотеки itertools. Она предоставляет около сотни полезных функций, решающих задачи по работе с массивами, строками и другими типами данных. Пара примеров:
from more_itertools import flatten, substrings
coll = [(0, 1), (2, 3)]
# делаем коллекцию плоской
print(list(flatten(coll))) # => [0, 1, 2, 3]
# получаем все подстроки строки
print([''.join(s) for s in substrings('more')])
# => ['m', 'o', 'r', 'e', 'mo', 'or', 're', 'mor', 'ore', 'more']
Каждая из этих функций по отдельности может выглядеть небольшой. Однако чем больше проект, тем больше требуется подобных функций, и все вместе они превращаются в довольно большую кодовую базу. А ведь еще хотелось бы иметь хорошую документацию.
Обратите внимание на то, как происходит импорт кода. Мы указываем лишь нужные нам функции из библиотеки, чтобы не загружать ее всю. В случае объемных библиотек с сотнями функций такой подход предпочтительнее.
# Так будет импортироваться вся библиотека
import more_itertools
# Так импортируется лишь функция flatten
from more_itertools import flatten
Установка
Если просто импортировать more-itertools в коде и затем запустить код на выполнение, то программа упадет с ошибкой: "more-itertools не найден". Для того чтобы воспользоваться сторонним пакетом, его нужно добавить в проект как зависимость. Так говорят потому, что код проекта теперь зависит от этих библиотек. Для этого в uv предусмотрена команда установки:
# Обязательно выполнять в корне проекта
# только тогда more-itertools будет лежать в правильном месте
uv add more-itertools
Эта команда выполняет три действия. Сначала она скачивает пакет из репозитория пакетов в директорию .venv в корне проекта. Если этой директории не было, то она автоматически создается. Затем она добавляет запись в pyproject.toml о том, что пакет more-itertools стал зависимостью. И наконец, создает или обновляет файл uv.lock.
tree -L 1
.
├── hexlet_hello_world
├── pyproject.toml
├── README.md
└── uv.lock
Зависимости в pyproject.toml добавляются под ключом dependencies
. Здесь указаны все пакеты, используемые в проекте и не входящие в стандартную библиотеку.
dependencies = [
"more-itertools>=10.5.0",
]
В качестве ключа в зависимостях указывается имя пакета. Именно это имя используется при импорте пакета. Значением является последняя доступная версия на момент скачивания.
Также мы можем посмотреть все дерево зависимостей командой uv tree
uv tree
hexlet-hello-world v0.1.0
└── more-itertools v10.5.0
На деле устройство директории .venv несколько сложнее, и об этом будет позже, но главное, что это директория, в которой хранятся все скачанные пакеты для нашего проекта.
Осталось разобраться с файлом uv.lock. Детально о нем будет позже в курсе, а сейчас опишем его общую концепцию.
Если кратко, то у зависимостей нашего проекта есть свои зависимости, такие же сторонние библиотеки, которые разработчики использовали для написания своих библиотек. А у них, в свою очередь, свои зависимости (зависимости зависимостей называются транзитивными зависимостями). Подобная цепочка может быть довольно длинной и на разных ее участках возможно появление одних и тех же пакетов, но разных версий. uv.lock содержит описание всех пакетов, которые будут поставлены, включая все их зависимости с указанием конкретных версий. Это позволяет получать гарантированно одни и те же версии зависимостей для всех разработчиков проекта. Этот файл, его называют lock-файл, используется для синхронизации зависимостей.
# Если мы хотим в точности те же версии всех пакетов,
# какие были у остальных разработчиков этого проекта
uv sync
Связь с GIT
Программисты не так часто делают проекты "с нуля". Чаще всего они работают с готовыми проектами. Проекты же, в свою очередь, хранятся в git-репозиториях. Что нужно хранить в репозитории, а что нет, когда мы говорим о зависимостях?
Код самих зависимостей не является частью исходного кода. Потому директорию .venv всегда добавляют в .gitignore. А вот файлы pyproject.toml и uv.lock являются важной частью исходного кода. Именно через них пакетный менеджер узнает о том, какие пакеты нужно поставить в систему.
Представьте, что вы клонируете готовый проект с GitHub на свой компьютер и сразу пробуете запустить. Он упадет с ошибкой, так как сами зависимости еще не скачаны в .venv, и сама директория отсутствует. Чтобы они появились, нужно запустить команду установки зависимостей из lock-файла проекта и файла описания проекта:
# Выполняется в корне проекта
# Устанавливает все указанные зависимости
uv sync
Эта команда скачивает зависимости в директорию .venv, базируясь на содержимом pyproject.toml и версиях из uv.lock.
Обновление и удаление зависимостей
Помимо добавления зависимостей uv
позволяет также обновлять текущие, указанные в pyproject.toml
uv sync --upgrade
Эта команда удалит устаревшие зависимости, скачает новые и пересоздаст lock-файл.
Теперь попробуем удалить ненужную нам зависимость из проекта.
uv remove more-itertools
Команда удалит зависимость и обновит lock-файл после.
Самостоятельная работа
- Добавьте
more-itertools
в ваш проект - Проверьте, что пакет добавился в зависимости в pyproject.toml
- Изучите самостоятельно содержимое директории .venv. В частности
.venv/lib/<ваша версия python>/site-packages
, найдите в ней установленный пакет. Посмотрите на его код, убедитесь что он совпадает с его кодом в репозитории - Добавьте изменения на Github. Проследите, чтобы .venv была добавлена в .gitignore
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.