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

Содержание статьи
Что такое модуль
Модуль - это любой файл с расширением .py. Его имя без расширения становится именем модуля: файл utils.py подключается как utils. Функции, классы и переменные из файла после импорта доступны через точку, например utils.greet(), поэтому одинаковые имена из разных модулей не конфликтуют.
По происхождению модули делят на три группы:
- стандартная библиотека:
math,os,json,datetimeи еще около двухсот модулей, которые ставятся вместе с интерпретатором; - сторонние пакеты из PyPI: requests, numpy, pandas, их устанавливают через pip;
- собственные файлы проекта, которые вы пишете сами.
Часть модулей стандартной библиотеки написана на C и встроена прямо в интерпретатор, например sys и builtins. Для программиста разницы нет: они подключаются тем же оператором.
Способы импорта
У оператора импорта несколько форм. Они отличаются тем, какие имена появляются в вашем коде.
import math # весь модуль, обращение math.sqrt()
import datetime as dt # модуль под коротким именем
from random import randint # одно имя без префикса
from os.path import join, exists # несколько имен через запятую
print(math.sqrt(16)) # 4.0
print(dt.date(2024, 1, 1).year) # 2024
print(randint(1, 6) in range(1, 7)) # True| Запись | Что появляется в коде | Когда использовать |
|---|---|---|
import math | Имя math | По умолчанию: сразу видно, откуда функция |
import numpy as np | Псевдоним np | Длинные имена и общепринятые сокращения |
from math import pi | Только pi | Одно-два часто используемых имени |
from math import * | Все публичные имена | Только в интерактивной консоли |
Импорт со звездочкой засоряет пространство имен и может незаметно перекрыть ваши переменные: если в модуле есть функция с тем же именем, что и у вас, побеждает та, что импортирована позже. Подробнее о стилях подключения и порядке строк импорта рассказано в статье об импорте библиотек.
Как написать свой модуль
Создайте файл geometry.py рядом с основным скриптом. Специального синтаксиса не требуется, это обычный код.
# geometry.py
import math
PI2 = 2 * math.pi
def circle_area(r):
return math.pi * r ** 2
def circle_length(r):
return PI2 * r
if __name__ == "__main__":
print(circle_area(1)) # выполнится только при прямом запуске файла# main.py
import geometry
from geometry import circle_length
print(round(geometry.circle_area(2), 2)) # 12.57
print(round(circle_length(1), 2)) # 6.28Зачем нужна проверка __name__
При импорте файл выполняется целиком сверху вниз. Если в модуле есть тестовые print() или запуск основной логики, они сработают в чужой программе. Переменная __name__ равна "__main__", только когда файл запущен напрямую, а при импорте в ней имя модуля. Поэтому код, который нужен лишь при самостоятельном запуске, прячут под эту проверку.
Повторный импорт
Модуль выполняется один раз за время работы программы, затем объект кешируется в словаре sys.modules. Повторный import просто берет его из кеша. Если вы поменяли файл в открытой консоли и хотите подгрузить изменения, вызовите importlib.reload(geometry).
Где Python ищет модули
Интерпретатор перебирает каталоги из списка sys.path по порядку и берет первый найденный файл с подходящим именем. Первым в списке стоит папка запускаемого скрипта, затем пути из переменной окружения PYTHONPATH, стандартная библиотека и папка site-packages с установленными пакетами.
import sys
for path in sys.path:
print(path)
print("json" in sys.modules) # загружен ли модуль jsonИз этого порядка следует частая ошибка начинающих: файл проекта, названный как стандартный модуль, например random.py или email.py, перекрывает настоящий модуль. В итоге import random подключает ваш файл, и вызов random.randint() заканчивается AttributeError. Переименуйте файл и удалите рядом с ним папку __pycache__.
Ошибка ModuleNotFoundError: No module named ... означает, что файл не найден ни в одном каталоге. Обычно пакет поставлен в другой интерпретатор: проверьте, что pip и скрипт используют одно и то же окружение, например командой python -m pip install имя. Изолировать зависимости проекта помогает виртуальное окружение.
Пакеты: модули в папках
Когда файлов становится много, их группируют в пакет. Пакет - это каталог с модулями, обычно с файлом __init__.py, который выполняется при первом импорте пакета. Начиная с Python 3.3 этот файл необязателен, но с ним поведение пакета предсказуемее.
shop/
__init__.py
models.py
services/
__init__.py
pricing.pyИмпорт идет через точку: from shop.services.pricing import discount. Внутри пакета можно использовать относительный импорт: в pricing.py запись from ..models import Product поднимется на уровень выше. Относительные импорты работают только внутри пакета, поэтому файл из пакета запускают как модуль: python -m shop.services.pricing, а не по пути к файлу.
Модули, которые нужны чаще всего
Короткая шпаргалка по стандартным и сторонним модулям, с которыми сталкивается почти каждый проект. Полный перечень разобранных библиотек собран в разделе модули и библиотеки.
| Модуль | Откуда | Для чего |
|---|---|---|
os, pathlib, shutil | Стандартная библиотека | Файлы, папки, пути |
sys | Стандартная библиотека | Аргументы запуска, пути поиска, выход из программы |
math, random, statistics | Стандартная библиотека | Вычисления и случайные числа |
datetime, time | Стандартная библиотека | Даты, время, паузы |
json, csv | Стандартная библиотека | Чтение и запись данных |
re | Стандартная библиотека | Регулярные выражения |
collections, itertools | Стандартная библиотека | Счетчики, очереди, комбинаторика |
logging | Стандартная библиотека | Журнал работы программы |
| requests | PyPI | HTTP-запросы к сайтам и API |
| numpy, pandas | PyPI | Массивы и табличные данные |
| matplotlib | PyPI | Графики |
| beautifulsoup4 | PyPI | Парсинг HTML |
| flask | PyPI | Веб-приложения |
| openpyxl, pillow | PyPI | Excel-файлы и изображения |
Чтобы быстро посмотреть, что есть внутри незнакомого модуля, вызовите dir(имя_модуля) или help(имя_модуля) в интерактивной консоли. Описание каждого стандартного модуля есть в официальной документации.
Частые вопросы
Ответы на вопросы, которые возникают при первом знакомстве с импортом.
Чем модуль отличается от библиотеки и пакета?
Модуль - один файл .py. Пакет - папка с модулями, которую можно импортировать как единое целое. Библиотека - неформальное название набора пакетов и модулей, решающего одну задачу, например pandas.
Как узнать, где лежит файл модуля?
Выведите атрибут __file__: import json; print(json.__file__). Для модулей, встроенных в интерпретатор, этого атрибута нет.
Как импортировать модуль из соседней папки?
Лучше оформить папки как пакет и запускать программу из корня проекта через python -m. Временное решение: добавить путь в sys.path.append("путь/к/папке") до строки импорта, но в рабочем коде так делать не стоит.
Можно ли импортировать модуль, имя которого хранится в строке?
Да, для этого есть importlib.import_module("json"). Функция возвращает объект модуля, его можно сохранить в переменную и вызывать функции через точку.