Python Relative Import не может найти пакет

Я уверен, что это довольно простая проблема, и я просто упускаю что-то невероятно очевидное, но ответ на это затруднительное положение ускользал от меня в течение нескольких часов.

Структура моего каталога проекта выглядит следующим образом:

-PhysicsMaterial
   -Macros
      __init__.py
      Macros.py
   -Modules
      __init__.py
      AvgAccel.py
      AvgVelocity.py
   -UnitTests
      __init__.py
      AvgAccelUnitTest.py
      AvgVelocityUnitTest.py
    __init__.py

Помимо критических замечаний относительно моих соглашений об именах и структуры каталогов, я не могу использовать относительный импорт. Я пытаюсь сделать относительный импорт файла модуля для тестирования в AvgAccelUnitTest.py:

from .Modules import AvgAccel as accel

Тем не менее, я продолжаю получать:

ValueError: Attempted relative import in non-package

Так как все мои файлы инициализации настроены по всей моей структуре, и у меня также есть верхний каталог, добавленный в мою PYTHONPATH, я озадачен. Почему python не интерпретирует пакет и правильно импортирует файл?

2 ответа

Решение

Это происходит потому, что вы запускаете скрипт как __main__, Когда вы запускаете такой скрипт:

python /path/to/package/module.py

Этот файл загружается как __main__не как package.moduleпоэтому он не может выполнять относительный импорт, потому что он не является частью пакета.

Это может привести к странным ошибкам, когда класс, определенный в вашем скрипте, будет определен дважды, один раз как __main__.Class и снова как package.module.Class, что может привести к isinstance проверки на провал и подобные странности. Из-за этого вы, как правило, не должны запускать свои модули напрямую.

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

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

Как исправить "Попытка относительного импорта в не-пакет" даже с __init__.py

Ну, думаю, что сейчас используется sys.path.append. Полтора хлопка @BrenBarn, @fireant и @Ignacio Vazquez-Abrams

Другие вопросы по тегам