Импорт модулей из соседних пакетов в Python без sys.path.insert

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

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

Python
Скопировать код
# В sibling_package/subpackage2/module2.py
# Позвольте представить вашего "соседа" – module1!
from ..subpackage1 import module1

Альтернативно, вы можете внести изменения в sys.path, добавив родительскую директорию:

Python
Скопировать код
import sys
from pathlib import Path
# Разрешите расширить sys.path, добавив в него родительскую директорию.
sys.path.append(str(Path(__file__).resolve().parent.parent))
from subpackage1 import module1

Учтите, что скрипты не стоит запускать напрямую как __main__ – это нарушает работу относительных импортов.

Кинга Идем в IT: пошаговый план для смены профессии

Структурирование проекта: скрипт установки и расположение пакетов

Продуманная структура проекта – залог успешной работы. Рекомендуем выполнить следующие действия:

  • Создайте файл setup.py, используя setuptools.setup(). Этот файл определит структуру вашего пакета и позволит "расставить все по местам".
Python
Скопировать код
# В файле setup.py
# "Вечеринка" начинается с setuptools.setup()!
from setuptools import setup, find_packages
setup(name='your_package', version='1.0', packages=find_packages())
  • Оформляйте пакеты так, чтобы они были папками вместе с файлом setup.py: файл __init__.py указывает Python'у, что здесь разместился валидный пакет для импорта.

  • Установите свой пакет в режиме разработки: команда pip install -e <path_to_your_project> позволит обновлять пакет без необходимости повторного его установления.

  • Воспользуйтесь виртуальными окружениями: они эффективно "оберегают" ваши проекты от конфликтов зависимостей, представляя собой своего рода "зоны отдыха" для различных проектов.

Правильный запуск скриптов

Чтобы избежать ошибок при работе с импортами:

  • Используйте python -m при запуске скриптов, которые представляют собой пакеты.
Bash
Скопировать код
# В командной строке:
# Давай дерзай, Python, настроимся на "m"!
python -m script
  • Для тестирования лучше сосредотачиваться на pytest – он сам будет управлять sys.path.

  • Файл setup.cfg стоит рассматривать как "информационный стенд" проекта, облегчающий его установку для других пользователей.

Импорт внутри пакета: верные пути

Вот некоторые рекомендации по импорту внутри вашего пакета:

  • Отдавайте предпочтение относительным импортам: они делают структуру вашего пакета более понятной и структурированной.

  • Следуйте руководству PEP для обеспечения лучшей совместимости между различными версиями Python.

  • Избегайте изменений в sys.path.insert: такие действия могут приводить к проблемам с поддержкой кода.

Визуализация

Представим структуру наглядно:

Markdown
Скопировать код
Здание (🏢): Этажи [1, 2, 3, 4]
Квартира А (🚪): Находится на 2 этаже
Квартира Б (🚪): На 3 этаже

Связь модулей внутри одного пакета выглядит так:

Markdown
Скопировать код
Чтобы перейти из 🚪А в 🚪Б, воспользуйтесь лифтом (🛗) или лестницей (🔼) внутри 🏢.

Суть заключается в следующем:

Markdown
Скопировать код
**Модули одного пакета** типа 🚪А и 🚪Б "проживают" под одной крышей (🏢) и могут без проблем перемещаться друг к другу.

Управление импортами в крупных проектах

Для того чтобы избежать хаоса в "танце импортов" в больших проектах, придерживайтесь следующих методик:

  • Упрощайте структуру проекта: если в вашем проекте слишком много "комнат", возможно стоит провести его оптимизацию.

  • Размещайте тесты внутри пакетов: тестовые файлы должны быть легко доступны, ведь это те "участники", с которыми все хотят взаимодействовать.

  • Отказывайтесь от ненужных файлов __init__.py: начиная с Python 3.3, хорошо работают неявные пакеты пространства имен без файлов __init__.py.

Готовность вашего проекта к будущему

Советы по обеспечению "долгосрочности" вашего проекта:

  • Создавайте такую структуру каталогов, которая поддерживает осуществление импорта модулей.

  • Периодически проводите рефакторинг для упрощения путей импорта.

  • Следите за актуальностью стандартов Python и вносите соответствующие изменения в ваш проект.

Полезные материалы

  1. Структурирование вашего проекта – Python Developer's Guide
  2. 6. Модули – Python's Doc 3.12.2
  3. PEP 328 – Многострочные и абсолютные/относительные импорты
  4. 5. Система импорта – Python's Doc 3.12.2
  5. Упаковка проектов Python – Python Packaging User Guide
  6. Как осуществить относительные импорты в Python? – Stack Overflow
  7. GitHub – navdeep-G/samplemod