Модуль 5 · Урок 5.3
Модули и части программы
import и from, собственный модуль и основной запуск, сторонние пакеты и разделение программы на части.
Наибольший общий делитель, точный квадратный корень, округление вверх — писать такие функции самому каждый раз незачем: они уже написаны и лежат в стандартной поставке Python. Готовые функции лежат в модулях, и import делает их доступными в программе. Модуль — это файл с такими же определениями, как в двух прошлых уроках, и свой код тоже удобно делить на части.
Начнём с модуля math и наибольшего общего делителя 18 и 24.
Модули и import
Модуль — файл с готовыми определениями; import подключает его по имени. Модули, которые приходят вместе с Python, составляют стандартную библиотеку; другие библиотеки ставят отдельно.
import math print(math.isqrt(50))print(math.gcd(18, 24))import math делает доступным имя модуля. Точка выбирает средство внутри него. isqrt возвращает точную целую часть квадратного корня неотрицательного целого: 7² = 49 не больше 50, а 8² = 64 уже больше. gcd находит наибольший общий делитель.
Другая форма импорта:
from math import isqrtprint(isqrt(50))Теперь в текущую область добавлено непосредственно имя isqrt. Запись import math as m задаёт короткое имя m. Обычно избегай from module import *: становится труднее понимать происхождение имён и конфликты.
import math даёт программе одно имя — модуль целиком, поэтому функции зовут через точку: math.isqrt. from math import isqrt берёт из модуля одно имя, и его зовут напрямую.В math есть и округления, и точное сложение дробных чисел. floor округляет вниз, ceil — вверх; fsum складывает дробные числа, не накапливая погрешность:
from math import ceil, floor, fsum print(floor(-2.5), ceil(-2.5))total = 0for _ in range(10): total += 0.1print(total, fsum([0.1] * 10))Цикл-накопитель десять раз прибавлял приближённое 0.1, и погрешности сложились. fsum учитывает их и даёт 1.0.
Не называй свой файл math.py, random.py или json.py, если собираешься импортировать одноимённый стандартный модуль: локальный файл может его заслонить.
Свой модуль
Свой модуль — это обычный файл; условие __name__ == "__main__" отделяет запуск от импорта. Файл calculations.py может содержать:
def square(number): return number * numberВ соседнем main.py:
from calculations import square def main(): print(square(7)) if __name__ == "__main__": main()При обычном прямом запуске файла его специальное имя __name__ равно "__main__". При импорте оно обычно равно имени модуля. Поэтому условие позволяет отделить использование определений от запуска пользовательского сценария: запуск main.py напечатает 49, а импорт main из другого файла ничего не напечатает.
calculations.py. Запущенный напрямую, он видит __name__ == "__main__" и выполняет блок под условием. Импортированный — видит своё имя модуля, и блок пропускается.Тонкости:что выполняется при импорте и что такое пакет
При первом импорте выполняется весь код модуля без отступа; повторный импорт берёт уже загруженный модуль. Поэтому input() на верхнем уровне модуля может остановить даже импорт. Связанные модули объединяют в пакет — папку с файлом __init__.py.
Сторонние пакеты
Сторонние пакеты ставят в виртуальную среду проекта. Зависимость — библиотека, которую использует проект. Виртуальная среда хранит отдельный набор установленных пакетов для проекта, чтобы разные проекты не мешали друг другу версиями. Она не является защитной песочницей для недоверенного кода.
Для примеров этого курса дополнительные пакеты не нужны, поэтому команды — в свёрнутом блоке.
Тонкости:виртуальная среда и pip
Команды терминала:
python -m venv .venv-m запускает модуль как программу. Здесь стандартный venv создаёт папку окружения. Можно использовать интерпретатор из неё напрямую, без активации:
.venv\Scripts\python -m pip --version.venv/bin/python -m pip --versionpip управляет установкой пакетов. Общая форма установки — python -m pip install имя_пакета, выполненная нужным интерпретатором. Важна связь: пакет установлен в конкретное окружение, а не «во все Python на компьютере».
Зависимости проекта можно перечислить с версиями в requirements.txt, а устанавливать командой python -m pip install -r requirements.txt. Для распространяемых современных проектов метаданные часто задаются в pyproject.toml; подробная упаковка — отдельный следующий этап.
Деление программы
Даже небольшую программу полезно делить на чтение, вычисление и вывод. Удобно отделять чтение данных, вычисление ответа и вывод. Тогда вычисляющую функцию можно проверять на обычных списках без подготовки файлов. Не нужно создавать десятки модулей ради десяти строк: разделяй по реальным самостоятельным задачам.
def count_multiples(a, b, d): count = 0 for n in range(a, b + 1): if n % d == 0: count += 1 return count def main(): print(count_multiples(1, 100, 7)) if __name__ == "__main__": main()count_multiples — тот же счётчик кратных, что в уроке о for, только оформленный функцией. Она ничего не знает о вводе и выводе: её можно вызвать с другими границами или проверить отдельно.
Итог
Готовые модули избавляют от лишней работы, а деление на функции делает программу проверяемой. Вот что понадобится дальше.
- import
import math— доступ черезmath.имя;from math import isqrt— имя напрямую. - Модуль math
math.isqrt,gcd,floor,ceil,fsum— точные готовые действия с числами. - Имя файлаСвой файл не называют как стандартный модуль.
__main__if __name__ == "__main__":выполняет запуск только при прямом запуске файла.- Части программыПрограмму делят на чтение, вычисление и вывод; вычисление проверяют отдельно.
Проверьте себя
Ответь сначала сам, потом открой ответ.
Почему функция average(numbers), которая только вычисляет среднее готового списка, удобнее функции, которая сама спрашивает путь, читает файл, вычисляет среднее и сразу печатает его?
ОтветСкрыть ответ
Первую функцию можно использовать с файлом, вводом, готовым списком или в другой программе. Её можно проверить вызовом average([2, 4]). Во втором варианте вычисление жёстко связано с конкретным вводом и выводом, поэтому повторное использование и проверка требуют лишних действий.
Как вызвать isqrt после import math и после from math import isqrt?
ОтветСкрыть ответ
math.isqrt(n) и isqrt(n).
Что произойдёт, если назвать свой файл math.py и написать в соседнем файле import math?
ОтветСкрыть ответ
Импортируется твой файл вместо стандартного модуля, и нужных функций в нём не окажется.
Чему равно __name__ в файле, который запустили напрямую, и в файле, который импортировали под именем calculations?
ОтветСкрыть ответ
"__main__" и "calculations".
Практика
Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.
Что напечатает программа?
import math print(math.isqrt(99))print(math.gcd(84, 36))Запишите напечатанные строки через пробел в порядке вывода.
Подсказка
isqrt — целая часть квадратного корня; gcd — наибольший общий делитель.
Разбор
9² = 81 ≤ 99 < 100 = 10²; НОД(84, 36) = 12.
Ответ: 9 12
Что напечатает программа?
from math import ceil, floor print(floor(2.7))print(ceil(2.1))print(floor(-0.5))Запишите напечатанные строки через пробел в порядке вывода.
Подсказка
floor — вниз, к меньшему целому; ceil — вверх.
Разбор
Вниз от 2.7 — 2, вверх от 2.1 — 3, вниз от −0.5 — −1.
Ответ: 2 3 -1
Напиши функцию: НОК через gcd
Напиши функцию lcm(a, b) для наименьшего общего кратного: НОК(a, b) = a · b // НОД(a, b), где НОД — math.gcd. Вызови её для 12 и 18, напечатав результат и запиши, что напечатала программа.
Введите число.
Подсказка
Импортируй gcd из math; верни a * b // gcd(a, b).
Разбор
Например:
from math import gcd def lcm(a, b): return a * b // gcd(a, b) print(lcm(12, 18))12 · 18 // 6 = 36.
Ответ: 36
Напиши программу: делится на 7, но не на 5
Сколько чисел от 1 до 1000 делятся на 7, но не на 5? Используй функцию count_multiples(a, b, d) из урока дважды. Посчитай кратные 7 и вычти кратные 35, запусти программу и запиши, что она напечатала.
Введите число.
Подсказка
Делящиеся на 7 и на 5 — это кратные 35: их нужно вычесть.
Разбор
Например:
def count_multiples(a, b, d): count = 0 for n in range(a, b + 1): if n % d == 0: count += 1 return count print(count_multiples(1, 1000, 7) - count_multiples(1, 1000, 35))Кратных 7 — 142, кратных 35 — 28: 142 − 28 = 114.
Ответ: 114