Ваши программы растут. В одном файле уже 200 строк, и вы начинаете путаться, где что лежит. Или вы написали полезную функцию и хотите использовать её в другом проекте. Копировать код? Плохая идея. В Python есть элегантное решение: модули и пакеты. Это способ разбивать код на отдельные файлы и собирать их как конструктор.
В этой статье:
- что такое модуль и как его импортировать,
- как создать свой первый модуль,
- разница между import, from import и as,
- как организовать пакет с несколькими файлами,
- главные ошибки новичков.
1. Модуль — это просто файл с кодом
В Python любой .py файл автоматически является модулем. Вы можете создать файл, написать в нём функции, а потом использовать их в другой программе.
Создадим модуль math_utils.py:
# math_utils.py
def add(a, b):
return a + b
def multiply(a, b):
return a * b
PI = 3.14159
Теперь в другом файле main.py импортируем этот модуль:
# main.py
import math_utils
print(math_utils.add(5, 3)) # 8
print(math_utils.PI) # 3.14159
Магия: Python находит файл math_utils.py и делает его содержимое доступным через пространство имён math_utils.
2. Способы импорта
Полный импорт (import module)
import math_utils
result = math_utils.add(2, 2)
Плюс: не засоряет глобальное пространство имён. Минус: каждый раз писать имя модуля.
Импорт конкретных имён (from module import name)
from math_utils import add, PI
print(add(2, 2)) # не нужно писать math_utils.
print(PI)
Импорт всего содержимого (from module import *)
from math_utils import *
print(multiply(2, 3))
Не рекомендуется — вы не видите, что именно импортируется, и возможны конфликты имён.
Псевдоним (as)
import math_utils as mu
print(mu.add(5, 5))
from math_utils import add as addition
print(addition(1, 2))
3. Где Python ищет модули?
Интерпретатор просматривает:
- папку, где находится запускаемый скрипт,
- переменную окружения PYTHONPATH,
- стандартные пути установки Python (например, site-packages).
Узнать все пути можно так:
import sys
print(sys.path)
Если ваш модуль лежит в другом месте, добавьте путь:
import sys
sys.path.append("/путь/к/папке")
import mymodule
4. Условный импорт и защита от запуска
Часто в модуле есть код, который должен выполняться только при прямом запуске файла, но не при импорте. Для этого используют конструкцию:
# math_utils.py
def add(a, b):
return a + b
if __name__ == "__main__":
# Этот код выполнится, только если запустить python math_utils.py
print("Тестирование модуля:")
print(add(2, 3))
Когда файл импортируется, __name__ равно имени модуля ("math_utils"), а не "__main__". Это позволяет совмещать в одном файле библиотеку и тесты.
5. Пакеты — модули в папках
Когда проектов становится много, складывать все .py файлы в одну кучу неудобно. Пакет — это папка, содержащая файлы модулей и специальный файл __init__.py (может быть пустым). Он говорит Python: «обращайся с этой папкой как с пакетом».
Структура:
my_package/
__init__.py
math_utils.py
string_utils.py
Импорт:
from my_package import math_utils
from my_package.string_utils import reverse_string
Внутри __init__.py можно определить, что импортируется по умолчанию:
# __init__.py
from .math_utils import add
from .string_utils import reverse_string
Тогда пользователь сможет писать:
from my_package import add, reverse_string
6. Установка сторонних модулей (pip)
В стандартной библиотеке Python много полезного, но ещё больше — создано сообществом. Установить любой пакет из Python Package Index (PyPI) можно через pip:
pip install requests
После этого в коде:
import requests
response = requests.get("https://api.github.com")
Популярные пакеты для новичков:
- requests — работа с HTTP,
- pandas — анализ данных,
- matplotlib — графики,
- pytest — тестирование.
7. Типичные ошибки новичков
❌ Циркулярный импорт
Файл A импортирует B, а B импортирует A. Python запутается. Решение — вынести общую логику в третий модуль или импортировать внутри функции.
❌ Имя модуля совпадает со стандартным
Не называйте свой файл random.py или json.py — он перекроет стандартный модуль, и всё сломается.
❌ Забыли __init__.py в пакете
В Python 3.3+ папка может считаться пакетом и без __init__.py (namespace packages), но для ясности и совместимости лучше добавлять пустой файл.
❌ Импорт внутри функции на каждый вызов
def bad():
import math # плохо: импорт при каждом вызове
return math.sqrt(4)
Импортируйте в начале файла.
8. Живой пример: рефакторинг игры в модули
Возьмём игру «Угадай число» из прошлых статей и разобьём на модули:
game_core.py — основная логика:
import random
def get_random_number(min_val, max_val):
return random.randint(min_val, max_val)
def check_guess(guess, secret):
if guess < secret:
return "БОЛЬШЕ", False
elif guess > secret:
return "МЕНЬШЕ", False
else:
return f"Угадал! Это {secret}", True
user_io.py — ввод/вывод:
def get_user_guess():
while True:
try:
return int(input("Твой вариант: "))
except ValueError:
print("Введи число!")
def print_message(msg):
print(msg)
main.py — запуск:
from game_core import get_random_number, check_guess
from user_io import get_user_guess, print_message
def play():
secret = get_random_number(1, 100)
print_message("Я загадал число от 1 до 100.")
while True:
guess = get_user_guess()
msg, done = check_guess(guess, secret)
print_message(msg)
if done:
break
if __name__ == "__main__":
play()
Теперь каждый модуль отвечает за свою задачу. Легко тестировать, легко заменять user_io на графический интерфейс, не трогая логику.
Заключение
Модули и пакеты — это шаг от скриптов к проектам. Вы научились:
- создавать свои модули,
- использовать разные виды импорта,
- организовывать пакеты с папками,
- устанавливать сторонние библиотеки.
Теперь ваш код может расти, не превращаясь в хаос. Следующая статья — введение в объектно-ориентированное программирование (классы), где мы поднимем организацию кода на новый уровень. А пока — возьмите любой свой проект и разбейте его на модули. Вы почувствуете разницу сразу.
Пишите в комментариях, какие модули вы написали сами или какие сторонние библиотеки используете чаще всего.
Статья подготовлена для канала «Код как искусство». Подписывайтесь, чтобы строить код как архитектуру из кирпичиков.