Основы модулей в Python: от простых файлов до пакетов
Основы модулей в Python
Модуль в Python это файл с расширением .py, содержащий определения функций, классов и переменных. Такой файл можно импортировать в другие скрипты, что позволяет переиспользовать код и поддерживать чистоту проекта.
Создание простейшего модуля: файл tools.py.
# tools.py
def greet(name):
return f"Привет, {name}!"
pi = 3.14159ввод данных на языке python (ввод данных в python)
Импорт и использование в другом файле (например, main.py):
# main.py
import tools
print(tools.greet("Анна"))
print(tools.pi)модули языка программирования python (модули в python)
Привет, Анна! 3.14159
После первого импорта интерпретатор создаёт объект модуля и кэширует его. Повторный import не перезагружает файл. Для перезагрузки используется importlib.reload().
Типичная ошибка:
ModuleNotFoundErrorвозникает, если Python не находит файл в путях поиска. Пути хранятся вsys.path. Решение: разместить модуль в текущей директории, добавить путь черезsys.path.append()или установить пакет.- В модуле не рекомендуется использовать исполняемый код с побочными эффектами (например, вызов
print()на верхнем уровне), так как он выполнится при первом импорте.
Как импортировать только отдельные имена, чтобы не загромождать пространство имён?
Вариант from module import name:
# main.py
from tools import greet, pi
print(greet("Максим"))
print(pi)
Плюс: не требуется префикс tools.. Минус: возможен конфликт имён, если в текущем пространстве уже есть greet или pi.
Конфликт имён решается переименованием при импорте:
from tools import greet as say_hello
print(say_hello("Иван"))
Как импортировать всё содержимое модуля одной командой?
Использование from module import *:
from tools import *
print(greet("Ольга"))
Такой подход не рекомендуется, потому что он вносит в область видимости все публичные имена модуля, что может привести к непредсказуемым переопределениям. Имена, начинающиеся с подчёркивания, не импортируются. Можно ограничить список импортируемых имён, определив в модуле список __all__.
Чтобы избежать хаоса, лучше явно перечислить нужные имена или использовать точечную нотацию (module.name).
Как организовать код в пакет (вложенные модули)?
Пакет это директория, содержащая файл __init__.py (может быть пустым) и модули. Пример структуры:
my_package/
__init__.py
math_utils.py
str_utils.py
Импорт из пакета:
import my_package.math_utils
# или
from my_package import str_utils
# или
from my_package.math_utils import factorial
Файл __init__.py может содержать код инициализации пакета, а также определять __all__ для управления from package import *.
Ошибка ImportError: attempted relative import with no known parent package возникает при попытке использовать относительные импорты (from . import something) в скрипте, запущенном как главный. Относительные импорты работают только внутри пакета.
Расширенные примеры работы с модулями
Пакет с несколькими модулями и общим интерфейсом
Создаётся пакет shapes для фигур.
# shapes/__init__.py
from .circle import area as circle_area
from .square import area as square_area
__all__ = ['circle_area', 'square_area']
# shapes/circle.py
import math
def area(radius):
return math.pi * radius ** 2
# shapes/square.py
def area(side):
return side * side
# main.py
from shapes import circle_area, square_area
print(circle_area(5))
print(square_area(4))
78.53981633974483 16
Динамический импорт модуля по имени (строка)
Используется importlib.import_module() для загрузки модуля, имя которого становится известно во время выполнения.
import importlib
module_name = "math"
math_mod = importlib.import_module(module_name)
print(math_mod.sqrt(25))
5.0
Такой подход применяется в плагинах и конфигурациях.
Проверка, импортирован ли модуль (sys.modules)
Словарь sys.modules содержит все загруженные модули.
import sys
if 'json' in sys.modules:
print("Модуль json уже импортирован")
else:
import json
print("Только что импортирован json")
Модуль json уже импортирован (если был ранее)
Модуль как исполняемый скрипт (if __name__ == '__main__')
В модуле можно разместить код, который выполняется только при запуске файла напрямую, а не при импорте.
# mymodule.py
def add(a, b):
return a + b
if __name__ == '__main__':
# тестовый запуск
print(add(2, 3))
При запуске python mymodule.py: 5 При импорте: ничего не выводится
Подавление повторных импортов
Python кэширует модули, но иногда нужно принудительно перезагрузить уже импортированный модуль.
import importlib
import mymodule
# после изменений в mymodule.py
importlib.reload(mymodule)
Обработка ошибок при импорте
try:
import nonexistent_module
except ImportError:
print("Модуль не найден. Установите его или проверьте путь.")