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