Гид по технологиям

Как создать, импортировать и повторно использовать собственный модуль в Python

5 min read Python Обновлено 23 Dec 2025
Как создать и повторно использовать модуль в Python
Как создать и повторно использовать модуль в Python

Как создать, импортировать и повторно использовать собственный модуль в Python — иллюстрация структуры проекта

Что такое модульность кода и зачем её использовать

Модульность — это разбиение программы на независимые части с чёткими обязанностями. Коротко: разделяйте ответственность, чтобы писать и тестировать код быстрее. Модульность помогает соблюдать правило “Не повторяйся” (DRY). Одна функция или класс реализует логику — вы вызываете её в нескольких местах вместо копирования кода.

Преимущества:

  • Улучшает читаемость и поддержку.
  • Упрощает тестирование компонентов.
  • Позволяет повторно использовать код в разных проектах.
  • Делает возможным изоляцию багов и профилирование узких мест.

Важно: модуль может быть простым набором функций или классом в файле .py. В статье мы покажем оба подхода на примере счётчика слов.

Объектно-ориентированное программирование в Python

OOP представляет код в виде классов и экземпляров. Класс описывает свойства (атрибуты) и поведение (методы). Экземпляры класса хранят состояние и вызывают методы.

Кратко по терминам:

  • Класс — шаблон для объектов.
  • Экземпляр — объект, созданный из класса.
  • Атрибут — данные, принадлежащие классу или экземпляру.
  • Метод — функция, связанная с классом.

OOP полезно, когда вам нужно объединять данные и операции над ними или наследовать и расширять поведение.

Практический пример: модуль счётчика слов

Ниже показан рабочий пример, как превратить небольшой скрипт в переиспользуемый модуль и как импортировать его из разных мест проекта.

Шаги:

  1. Создайте каталог проекта (пример названия — word_count):
mkdir word_count
  1. Создайте виртуальное окружение и активируйте его (по желанию). Убедитесь, что находитесь в каталоге проекта.

Создание каталога проекта и виртуального окружения

  1. Создайте файл counter.py в каталоге, содержащий класс WordCounter.

Пример простого рабочего скрипта (для идеи):

sentence = 'how to make a reusable word counter in python'
words = sentence.split(' ')
count = sum(1 for word in words if word)
print(count)  # 9

Преобразим это в класс в файле counter.py:

class WordCounter:
    """Класс для подсчёта слов в строке."""

    def count_words(self, sentence: str) -> int:
        """Возвращает количество непустых слов в предложении.

        Один строковый аргумент, разделитель — пробел. Это минимальная реализация.
        """
        if sentence is None:
            return 0
        words = sentence.split(' ')
        count = sum(1 for word in words if word)
        return count

Теперь у вас есть переиспользуемый модуль — файл counter.py с классом WordCounter.

Импорт модуля из той же папки

Если другой скрипт лежит в той же папке, импорт прост:

Создайте файл main.py в той же папке и напишите:

from counter import WordCounter

sentence = "how to import and reuse your code in Python"
counter = WordCounter()
print(counter.count_words(sentence))  # 7

Пояснения:

  • Python ищет модуль в текущем каталоге, затем в sys.path.
  • Имена файлов и классов чувствительны к регистру на большинстве ОС.

Импорт модуля из другой папки

Если файл, который импортирует модуль, находится в другой папке проекта, есть несколько подходов. Мы рассмотрим три безопасных варианта: пакеты с init.py, относительный импорт внутри пакета и установка разработки через pip (-e).

1) Пакет с init.py и абсолютный импорт

Структура проекта:

word_count
├─ destination
│  └─ destination.py
└─ wordcount
   ├─ __init__.py
   └─ counter.py

Файл wordcount/init.py можно оставить пустым или экспортировать класс:

from .counter import WordCounter

__all__ = ["WordCounter"]

В destination.py используйте абсолютный импорт:

from wordcount.counter import WordCounter

sentence = 'import and reuse your Python code from files with different paths'
counter = WordCounter()
print(counter.count_words(sentence))

Важно: чтобы Python видел пакет wordcount при запуске destination.py напрямую, точка запуска должна быть корнем проекта (т.е. запустить python -m destination.destination или настроить PYTHONPATH). Лучше запускать скрипт из корня проекта:

cd word_count
python destination/destination.py

2) Относительный импорт внутри пакета

Если destination — также пакет, можно применять относительный импорт. Структура:

word_count
└─ app
   ├─ __init__.py
   ├─ destination.py
   └─ wordcount
       ├─ __init__.py
       └─ counter.py

В destination.py:

from .wordcount.counter import WordCounter

Запускать модуль следует как пакет:

python -m app.destination

3) Установка в editable режиме (pip install -e)

Для реальных проектов и многократного использования удобнее оформить пакет и установить его в виртуальном окружении:

  • Создайте pyproject.toml или setup.cfg и setup.py (в простом виде). Затем выполните:
pip install -e .

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

Временный трюк с sys.path

Иногда встречается код, расширяющий sys.path вручную:

import sys
sys.path.append(sys.path[0] + "/..")
from wordcount.counter import WordCounter

Это быстро решает проблему при запуске из IDE или скрипта, но не является хорошей практикой для долгосрочного проекта. Используйте его только для локального теста.

Дополнительные рекомендации и улучшения модуля

  • Добавьте обработку пунктуации и множественных пробелов, если нужна точная статистика.
  • Предусмотрите опцию нормализации регистра (lowercase) при подсчёте уникальных слов.
  • Напишите юнит-тесты для класса WordCounter.
  • Документируйте поведение в docstring и README.

Пример расширенного метода:

import re

class WordCounter:
    def count_words(self, sentence: str) -> int:
        if not sentence:
            return 0
        words = re.findall(r"\b\w+\b", sentence)
        return len(words)

Это регулярное выражение считает слова как последовательности буквенно-цифровых символов, игнорируя пунктуацию.

Тесты и критерии приёмки

Критерии приёмки для базового модуля:

  • Функция должна возвращать 0 для пустой строки или None.
  • Для строки “hello world” должно вернуть 2.
  • Для строки с пунктуацией и пробелами результат должен быть корректным.
  • Методы должны иметь предсказуемые типы входа и выхода (str -> int).

Пример простого pytest теста (tests/test_counter.py):

from wordcount.counter import WordCounter

def test_empty():
    assert WordCounter().count_words('') == 0

def test_simple():
    assert WordCounter().count_words('hello world') == 2

def test_punctuation():
    assert WordCounter().count_words('hello, world!') == 2

Когда модульность не помогает — контрпримеры и ограничения

  • Для однострочных скриптов, которые никогда не будут поддерживаться, создание модуля может быть излишним.
  • Переусложнение интерфейса (слишком много параметров) делает повторное использование труднее.
  • Если у вас есть высоконагруженные узлы, простая рефакторинг-модуль может не решить проблем производительности — нужно профилировать.

Безопасность и приватность

  • Не храните в модуле секреты (пароли, ключи). Используйте переменные окружения или менеджеры секретов.
  • При импорте динамических модулей избегайте выполнения непроверённого кода через importlib или exec.

Шаблон плейбука для создания и распространения модуля

  1. Выделите ответственность — одна задача на модуль.
  2. Напишите чистую реализацию и docstring.
  3. Добавьте юнит-тесты.
  4. Создайте пакет (pyproject.toml) и README.
  5. Установите в editable режим для разработки: pip install -e .
  6. Документируйте API и примеры использования.

Чех-лист ролей

Для разработчика:

  • Есть docstring и README.
  • Написаны тесты.
  • Обработаны граничные случаи.

Для тимлида:

  • Интерфейс прост и понятен.
  • Нет глобальных побочных эффектов.

Для тестировщика:

  • Покрытие тестами критичных сценариев.
  • Проверки на некорректные входные данные.

Быстрая памятка по импортам (cheat sheet)

  • Локальный импорт в той же папке: from module import Class
  • Абсолютный импорт из пакета: from package.module import Class
  • Относительный импорт внутри пакета: from .module import Class
  • Установка пакета: pip install -e .

Пример структуры для реального проекта

word_count/                # корень проекта
├─ pyproject.toml
├─ README.md
├─ wordcount/              # пакет с кодом
│  ├─ __init__.py
│  └─ counter.py
└─ tests/
   └─ test_counter.py

Ментальные модели и эвристики

  • Делайте модули маленькими и автономными.
  • Если вы тянете один и тот же файл в три проекта — сделайте из него пакет.
  • Тесты — главный индикатор пригодности к повторному использованию.

Краткий итог

Повторное использование кода в Python делается легко: оформите файл как модуль или пакет, выберите подходящий тип импорта и тестируйте. Для небольших проектов хватает простого импорта по пути, для устойчивых решений — оформляйте пакет и используйте editable-установку или публикуйте пакет.

Important: избегайте изменения sys.path в продакшн-коде и не храните секреты в модуле.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как включить iCloud Photos и синхронизировать фото
Технологии

Как включить iCloud Photos и синхронизировать фото

Aitum Vertical Plugin для OBS — вертикальный стриминг
Стриминг

Aitum Vertical Plugin для OBS — вертикальный стриминг

Как отформатировать SD‑карту на Mac
Руководство

Как отформатировать SD‑карту на Mac

Перенос чатов WhatsApp с iPhone на Android
Мобильные устройства

Перенос чатов WhatsApp с iPhone на Android

Как снимать ночью: избавляемся от смаза
Фотография

Как снимать ночью: избавляемся от смаза

Как блокировать мошеннические номера и спам‑звонки
Безопасность

Как блокировать мошеннические номера и спам‑звонки