#python #import #importerror #directory-structure #modulenotfounderror
#python #импорт #ошибка импорта #структура каталогов #modulenotfounderror
Вопрос:
Исследуя, как я должен структурировать свои проекты и тесты, я клонировал в репозиторий nose и обнаружил ту же проблему, что и у меня.
Вот как структурирован проект:
nose <----- repository root
nose <- source root
__main__.py
__init__.py
core.py
[...]
unit_tests
.gitignore
[...]
Если я запускаю
python nose/__main__.py
Я получаю
File "/home/daniel/Projects/nose/nose/__main__.py", line 3, in <module>
from nose.core import run_exit
ModuleNotFoundError: No module named 'nose'
Я понимаю, что, вероятно, есть исправление, связанное PYTHONPATH
с Python, но, будучи довольно новичком в Python, я чувствую, что должен быть способ, чтобы проект работал «из коробки» без необходимости возиться с какими-либо системными переменными.
Для контекста все это расследование началось с того, что я обнаружил, что мои тесты завершились неудачей, потому что импорт в моем нетестовом коде завершится неудачей (структура моего проекта такая же, как у Nose). Например:
from package import module
from package.subpackage import module
Приведет к следующей ошибке при выполнении тестов:
ModuleNotFoundError: No module named 'package'
Тесты будут работать нормально, если я изменю свой импорт, чтобы он был похож на nose. Например:
from project.package import module
from project.package.subpackage import module
Но тогда я столкнулся с вышеупомянутой ошибкой при попытке запустить программу в обычном режиме.
ModuleNotFoundError: No module named 'project'
Комментарии:
1. Корневой каталог при выполнении ваших тестов и при запуске вашего приложения должен отличаться. Можете ли вы распечатать первый элемент
sys.path
при запуске ваших тестов и при запуске вашего приложения, чтобы увидеть, есть ли разница?2. @SpaceBurger вы правы, при запуске моих тестов путь — это корень тестов (project / test), а при запуске моего приложения путь — это корень моих источников (project / project)
3. Тогда самым прямым решением было бы добавить каталог вашего источника перед
sys.path
(с помощью простогоsys.path.insert(abs_path_to_sources_root))
. Таким образом, вам не нужно изменять импорт в своих источниках или тестах. Однако это должно быть запущено до начала любых тестов; возможно, в вашем тестовом модуле есть опция, которая может делать это автоматически, и вам даже не нужно писать код. Другим решением было бы поместить ваши тесты вместе с вашим кодом, но я не знаю, рекомендуется ли это. Зависит от того, какой у вас модуль тестирования.