У меня есть следующая структура проекта:
- project
- src
- module_a
- foo.py
- __init__.py
- runner.py
- constants.py
- __init__.py
константы.py:
SOME_CONST = 5
фу.py:
from src.constants import SOME_CONST
class Foo:
def some_func(self):
....
бегун.py:
from src.module_a.foo import FOO
def main():
Foo.some_func()
if __name__ == "__main__":
main()
Я пытаюсь запустить python runner.py из папки src, но мне выдается сообщение ModuleNotFound о src, когда foo.py пытался импортировать from src.constants import SOME_CONST.
Я понимаю, что проблема заключалась в том, что интерпретатор Python не распознал папку src как модуль, хотя в ней есть файл __init__.py.
После создания виртуальной среды venv проблема была решена.
У меня есть следующие вопросы:
src как модуль перед созданием виртуальной среды?@chepner почему? если у меня есть константы или служебные функции, которые являются общими для всего проекта, разве они не должны находиться непосредственно в src и использоваться всеми модулями (а это означает, что мне нужно, чтобы src был модулем)?
Вы можете хранить их в каталоге src; это не означает, что src определяет один пакет Python. runner.py — это скрипт, а не модуль.
В чем заключалось сообщение об ошибке? «ModuleNotFoundError: нет модуля с именем «FOO»»?
@PeterMortensen «ModuleNotFoundError: нет модуля с именем 'src'», и ошибка была выдана из foo.py из строки from src.constants import SOME_CONST.






Вы не должны рассматривать src как пакет, а скорее как каталог, который будет добавлен в sys.path при выполнении runner.py. Таким образом, constants и module_a являются модулями верхнего уровня, а не подмодулями пакета src.
константы.py:
SOME_CONST = 5
фу.py:
from constants import SOME_CONST
class Foo:
def some_func(self):
....
бегун.py:
from module_a.foo import FOO
def main():
Foo.some_func()
if __name__ == "__main__":
main()
При установке в виртуальную среду module_a и constants следует устанавливать в venv/lib, а runner.py следует устанавливать в venv/bin, что нарушает ваше прежнее предположение, что runner.py и модули все находятся в одном каталоге.
Спасибо! Должен ли я добавить его к sys.path в скрипте runner.py? Кроме того, если я хочу контейнеризировать проект — должна ли у меня быть команда для добавления каталога src в sys.path в файле docker?
Кроме того, почему создание venv решило проблему?
Нет, src должен быть «релевантным» только для вашего исходного репозитория. runner.py можно установить в /usr/bin, а module_a и constants можно установить, например, в /usr/lib/python/site-packages.
Как вы установили код в виртуальную среду?
python -m venv C:\path_to_project\src.
Это просто создает виртуальную среду с вашим переводчиком в C:\path_to_project\src\bin\python. На самом деле вы вообще не устанавливаете свой код, а создаете вокруг него виртуальную среду. Ни один из ваших кодов не находится в нужном месте.
Я понимаю, но из любопытства - почему устранилась ошибка ModuleNotFound?
Не используйте
srcкак пакет; считайте «совпадением», чтоrunner.pyи два ваших модуля верхнего уровня теперь находятся в одном каталоге.