Перейти к содержимому
k06

k06. Mодули, пакеты, venv и pip.

k06. Mодули, пакеты, venv и pip.

UAV Python Pro · Конспект K06 · Модуль M1. Python intensive: модули, пакеты, venv и pip · Редакция 1.1 · После CHECKPOINT-K05

На занятии K05 вы научились собирать логику программы в функции. Когда функций становится много, все их невозможно хранить в одном файле: такой проект перестаёт быть читаемым. На этом занятии вы разберёте, каким образом Python раскладывает код по файлам и папкам, как подключать собственный код с помощью оператора import, для чего необходимо виртуальное окружение venv, которое вы уже создали на занятии K01, и как аккуратно устанавливать библиотеки с помощью инструмента pip. Это материал является непосредственной подготовкой к установке библиотеки pymavlink и других инструментов курса. Практические задания выполняются в виртуальном окружении проекта K01; соответствующие файлы расположены в каталоге code/M01_python/k06_*.py.

Главная мысль занятия состоит в следующем: один файл должен соответствовать одному понятному фрагменту ответственности. Готовый чужой код подключается как библиотека с помощью инструмента pip в виртуальное окружение, тогда как собственный код подключается с помощью оператора import. Команда python -m pip устанавливает пакеты именно в тот интерпретатор Python, которым вы пользуетесь в данный момент. Файл зависимостей, который называется requirements, необходим для того, чтобы через месяц или на устройстве Raspberry Pi можно было воспроизвести тот же самый набор библиотек.

Рабочие файлы: code/M01_python/k06_task1_import_units.py и соседние файлы, имена которых начинаются с префикса k06_.

Содержание

1. Цели урока

По завершении этого занятия вы будете обладать следующими умениями.

  • Вы сможете объяснить, чем модуль отличается от пакета.
  • Вы научитесь импортировать собственный учебный модуль с помощью оператора import и конструкции from … import.
  • Вы научитесь использовать конструкцию if __name__ == "__main__" и объяснять, для чего она предназначена.
  • Вы научитесь проверять, что инструмент pip устанавливает пакеты в активное виртуальное окружение, а не в посторонний интерпретатор Python.
  • Вы научитесь выполнять команду python -m pip freeze и понимать смысл файла зависимостей.
  • Вы сможете описать словами структуру папок учебного проекта курса.
  • Вы научитесь воздерживаться от установки библиотек в системный интерпретатор Python только потому, что такой способ кажется более быстрым.
Значение этого материала для работы с БПЛА: библиотеки pymavlink, pyserial, opencv и другие являются внешними пакетами. Сервис, который выполняет роль спутника на устройстве Raspberry Pi, должен запускаться из понятного виртуального окружения с зафиксированными версиями библиотек. Без соблюдения дисциплины использования операторов import и pip проект, который «работает дома», может перестать работать на борту аппарата.
↑ К оглавлению

2. Словарь урока

ТерминОбъяснение простыми словами
Модуль Один файл с расширением .py, из которого можно импортировать функции и переменные.
Пакет Папка, в которой содержатся модули обычно вместе с файлом __init__.py; оператор import воспринимает такую папку как единое пространство имён.
import Команда, которая подключает модуль или пакет, чтобы можно было пользоваться его содержимым.
venv Виртуальное окружение — отдельный изолированный интерпретатор Python со своим набором установленных пакетов для данного проекта.
pip Программа, которая устанавливает и обновляет пакеты Python.
PyPI Каталог готовых пакетов, который расположен в интернете и из которого инструмент pip обычно загружает пакеты.
requirements.txt Текстовый файл, который содержит список зависимостей проекта, то есть перечень необходимых пакетов.
dependency / зависимость Внешняя библиотека, без которой код не сможет запуститься.
__name__ Специальная переменная Python, значение которой показывает, был ли файл запущен как программа или был импортирован как модуль.
↑ К оглавлению

3. Зачем делить код на файлы

Пока размер кода составляет от тридцати до пятидесяти строк, хранение всего кода в одном файле является допустимым. Когда же в проекте появляются такие задачи, как разбор телеметрии, построение миссии, запись журналов, связь по протоколу MAVLink и обработка данных с камеры, единственный файл превращается в беспорядочный набор инструкций.

Разделение кода по файлам даёт следующие преимущества.

  • Появляются понятные границы между частями программы: один файл содержит только функции перевода единиц измерения, другой файл содержит только печать отчёта.
  • Появляется возможность повторного использования кода: одну функцию можно импортировать из двух различных скриптов.
  • Упрощается тестирование кода и чтение изменений, которые показывает система контроля версий Git.
Правило курса. Учебные скрипты, имена которых имеют вид kNN_task*.py, могут оставаться точками входа в программу. Общую логику, которую вы собираетесь использовать многократно, следует выносить в модули, расположенные внутри пакета.
↑ К оглавлению

4. Модуль и пакет

Что такое модуль

Модуль в языке Python представляет собой, по существу, один файл с расширением .py. Когда вы записываете оператор import, интерпретатор Python загружает этот файл и делает его функции доступными для использования.

Примером из практики занятия служит файл units.py, который находится внутри учебного пакета и является модулем с функциями перевода единиц измерения.

# фрагмент sensors/units.py (полный файл находится в материалах)
def alt_cm_to_m(alt_cm: int) -> float:
    """Сантиметры → метры."""
    return alt_cm / 100.0

Что такое пакет

Пакет представляет собой папку, в которой расположены модули и которую интерпретатор Python может импортировать как единое пространство имён. Обычно в такой папке присутствует файл __init__.py, который может быть и пустым. Именно этот файл помечает папку как пакет.

Учебная структура, которая используется на занятии K06, выглядит следующим образом:

code/M01_python/k06_demo_package/
    sensors/
        __init__.py
        units.py

В этой структуре папка sensors является пакетом, а файл units.py является модулем, который расположен внутри данного пакета.

Аналогия. Модуль можно сравнить с одним документом, который лежит в папке. Пакет можно сравнить с самой папкой, в которой собраны документы на одну тему. Оператор import соответствует действию «открыть нужный документ из нужной папки».
↑ К оглавлению

5. Оператор import и конструкция from … import

import — это команда, которая подключает модуль или пакет. После выполнения импорта вы можете вызывать функции либо через имя модуля, либо импортировать отдельные имена напрямую.

Рассмотрим два часто используемых способа записи.

# Способ 1: импорт модуля целиком, вызов функции через имя модуля
import math
print(math.sqrt(9))

# Способ 2: импорт конкретных имён из модуля
from math import sqrt
print(sqrt(9))

Для учебного пакета sensors, который рассматривается в задании k06_task1, применяется следующая запись:

# После настройки sys.path (в учебном файле задания это выполнено явно)
from sensors.units import alt_cm_to_m, voltage_label

print(alt_cm_to_m(2500))
print(voltage_label(15.556))
Конструкция from module import *, которая выполняет импорт всех имён сразу, на этом курсе не используется. При её применении становится непонятно, откуда взялось то или иное имя, и легко случайно переопределить собственную переменную функцией, импортированной из чужого модуля.
Ожидаемый вывод задания task1: число 25.0 и строка вида 15.56 V.
↑ К оглавлению

6. Конструкция if __name__ == "__main__"

У каждого файла Python имеется специальная переменная __name__. Её значение зависит от того, каким способом был запущен данный файл.

  • Если файл был запущен напрямую, то есть командой Run в среде PyCharm или командой python file.py, то переменная __name__ принимает значение "__main__".
  • Если файл был импортирован из другого файла, то переменная __name__ принимает значение имени этого модуля, а не строку "__main__".

Именно поэтому применяется так называемая «охрана main», то есть проверка точки входа:

def greet(name: str) -> str:
    return f"hello, {name}"


def main() -> None:
    # Код, который нужен только при запуске файла как программы
    print(greet("uav-dev"))


if __name__ == "__main__":
    main()
Для чего это необходимо. При импорте файла не должен сам по себе запускаться основной код, который, например, печатает сообщения, подключается к порту или отправляет команды. При прямом запуске файла такой код, напротив, должен выполняться. Данная конструкция является базовым правилом для скриптов наземной станции управления и для программ спутника.
Практика. Файл k06_task2_main_guard.py необходимо запустить напрямую; при этом на экране появится приветствие. Проверку поведения при импорте этого файла как модуля можно выполнить позже, когда работа с пакетами станет более привычной.
↑ К оглавлению

7. Виртуальное окружение venv и инструмент pip

venv — напоминание

venv, то есть виртуальное окружение, представляет собой отдельную изолированную среду Python для проекта: у неё собственный интерпретатор и собственный набор установленных пакетов. На занятии K01 вы уже создали такое окружение в среде PyCharm. Здесь мы закрепляем смысл этого понятия.

Виртуальное окружение необходимо по следующим причинам.

  • Проект A может использовать одну версию библиотеки pymavlink, а проект B — другую версию этой библиотеки.
  • Системный интерпретатор Python в операционной системе Windows не загрязняется лишними пакетами.
  • На устройстве Raspberry Pi упрощается воспроизведение того же самого окружения.

Проверить, что вы работаете в виртуальном окружении проекта, можно следующим образом:

import sys
print(sys.executable)
# В пути должно присутствовать нечто вроде ...\.venv\Scripts\python.exe

Инструмент pip — установка пакетов

pip — это стандартная программа установки пакетов Python. Пакеты, как правило, располагаются в каталоге PyPI, то есть в индексе пакетов Python, который находится в интернете.

Правильная форма команды для этого курса выглядит так:

python -m pip install имя_пакета

Разберём эту команду по частям.

  • python — это тот интерпретатор, который является активным в данный момент (желательно, чтобы это был интерпретатор из виртуального окружения);
  • -m pip — означает «запусти модуль pip именно этим интерпретатором python»;
  • благодаря такой форме снижается вероятность того, что сработает посторонний инструмент pip, который принадлежит другому интерпретатору Python и был найден в переменной PATH.
Чего пока делать не следует. Не устанавливайте случайные пакеты «из интереса» и не выполняйте установку пакетов в системный интерпретатор Python. На этом курсе перечень библиотек будет вводиться постепенно, по мере изучения модулей (библиотека pymavlink будет рассмотрена в блоке MAVLink).
# Обновить сам инструмент pip внутри виртуального окружения (безопасно и полезно)
python -m pip install -U pip

# Посмотреть, какие пакеты уже установлены
python -m pip list

Файл requirements и команда freeze

requirements.txt — это текстовый файл, который содержит список зависимостей проекта, то есть перечень необходимых пакетов, часто с указанием номеров версий.

Команда freeze выводит на экран фактически установленные пакеты текущего окружения:

python -m pip freeze

Снимок установленных пакетов можно сохранить в файл (это действие носит учебный характер):

python -m pip freeze > requirements-lock-demo.txt
Два уровня понимания (пока без излишнего усердия). Первый уровень — «человеческий» файл requirements.txt, который содержит основные пакеты курса. Второй уровень — «строгий снимок», который создаёт команда freeze и который служит для точного воспроизведения версий пакетов. В модуле M1 достаточно понять назначение обеих команд. Позднее мы зафиксируем рабочий файл requirements.txt для библиотеки pymavlink.
Практика задания task3. Файл k06_task3_pip_freeze_note.py лишь напоминает о необходимых шагах. Команды для инструмента pip вы должны выполнить самостоятельно в терминале виртуального окружения и изучить результат выполнения команды freeze.
↑ К оглавлению

8. Структура проекта курса (как поддерживать порядок)

uav-python-pro/                 ← корень репозитория Git и проекта PyCharm
  .venv/                        ← виртуальное окружение (не сохраняется в репозиторий)
  .gitignore
  code/
    M01_python/
      k03_*.py … k06_*.py       ← точки входа и практические задания
      k06_demo_package/
        sensors/
          __init__.py
          units.py              ← переиспользуемый модуль
  docs/                         ← ваши заметки (по желанию)
Полезная привычка. «Скрипт урока» может оставаться простым. Общая логика, которую вы планируете вызывать из двух и более мест, должна размещаться в пакете или модуле. Тем же способом мы позднее разместим модули mavlink_helpers, mission_builder и другие.
↑ К оглавлению

9. Типичные ошибки

ОшибкаЧто вы наблюдаетеКак следует рассуждать
Ошибка ModuleNotFoundError Интерпретатор Python не находит модуль или пакет Проверьте имя модуля, расположение папки, переменную sys.path и то, что запуск выполняется из ожидаемого каталога
Инструмент pip установил пакет «не туда» Оператор import в среде PyCharm не видит установленный пакет Проверьте значение sys.executable; всегда используйте команду python -m pip
Работа без виртуального окружения Возникают конфликты версий, поведение отличается от ожидаемого Вернитесь к интерпретатору из каталога .venv в настройках PyCharm
Код на верхнем уровне модуля отправляет команды при импорте Побочные эффекты возникают при импорте из другого файла Скрывайте запуск за конструкцией if __name__ == "__main__"
Применение конструкции from x import * Непонятно происхождение имён в коде Импортируйте имена явно
↑ К оглавлению

10. Практика

Задача 6.1. Импорт собственного модуля

Файл k06_task1_import_units.py и пакет k06_demo_package/sensors. Запустите задачу task1 и получите значение 25.0 и строку с напряжением.

Задача 6.2. Охрана main

Файл k06_task2_main_guard.py. Запустите его напрямую. Убедитесь, что вы понимаете: при импорте этого файла функция main не должна вызываться сама по себе.

Задача 6.3. Команда pip freeze в виртуальном окружении

В терминале виртуального окружения выполните команды python -m pip install -U pip и python -m pip freeze. При желании сохраните результат команды freeze в файл. Случайные пакеты не устанавливайте.

Задача 6.4. Запись изменений в репозиторий

git add code/M01_python/k06_*.py code/M01_python/k06_demo_package
git commit -m "K06: modules package import main guard pip freeze"
↑ К оглавлению

11. Проверьте себя

  1. Чем модуль отличается от пакета? Приведите пример из структуры k06_demo_package.
  2. Для чего нужен файл __init__.py в учебном пакете?
  3. Чем запись import math отличается от записи from math import sqrt?
  4. Что означает конструкция if __name__ == "__main__"? Что произойдёт, если убрать эту проверку и оставить код запуска, который выполняется при импорте?
  5. Почему мы записываем команду python -m pip, а не просто pip?
  6. Зачем необходимо виртуальное окружение, если «и так всё устанавливается»?
  7. Что выводит на экран команда pip freeze?
  8. Почему не следует устанавливать пакеты в системный интерпретатор Python «на авось»?
↑ К оглавлению

12. Чек-лист самопроверки

  • Я объясняю своими словами, что такое модуль и что такое пакет.
  • Я запустил задачу k06_task1 и увидел ожидаемый результат.
  • Я понимаю смысл конструкции if __name__ == "__main__".
  • Значение sys.executable указывает на каталог .venv проекта.
  • Я умею выполнять команды python -m pip list и python -m pip freeze.
  • Я не устанавливаю пакеты за пределами виртуального окружения.
  • Я понимаю, для чего в будущем понадобится файл requirements.
  • Я записал изменения по занятию K06 в репозиторий с помощью git.
Результат: Следующим занятием является K07, посвящённое работе с файлами и форматами JSON, CSV, YAML, а именно с журналами телеметрии и конфигурациями миссий, которые хранятся на диске.
↑ К оглавлению

13. Что дальше

  • Предыдущее занятие: K05 · Циклы и функции.
  • Текущее занятие: K06 · Модули, пакеты, venv, pip.
  • Следующее занятие: K07 · Файлы и форматы данных.
  • Горизонт модуля M1: занятие K12 «CLI Fake GCS» и контрольный рубеж G1.
Требование к вёрстке, начиная с K06. Первое определение каждого нового термина следует заключать в элемент span с классом uk-marker; это правило описано в руководстве редактора. Указание содержится в документе docs/05_EDITOR_STYLE_GUIDE.md, правило R13.
↑ К оглавлению

 

 

Пятница, 14 августа 2026
k06. Mодули, пакеты, venv и pip.