Python: модуль не найден: почему venv решил эту проблему?

У меня есть следующая структура проекта:

- 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 проблема была решена.

У меня есть следующие вопросы:

  1. Почему интерпретатор Python не распознал папку src как модуль перед созданием виртуальной среды?
  2. Почему создание виртуальной среды решило проблему?
  3. Как настроить проект, чтобы он работал без установки виртуальной среды?

Не используйте src как пакет; считайте «совпадением», что runner.py и два ваших модуля верхнего уровня теперь находятся в одном каталоге.

chepner 19.05.2024 17:37

@chepner почему? если у меня есть константы или служебные функции, которые являются общими для всего проекта, разве они не должны находиться непосредственно в src и использоваться всеми модулями (а это означает, что мне нужно, чтобы src был модулем)?

Eyal Golan 19.05.2024 17:40

Вы можете хранить их в каталоге src; это не означает, что src определяет один пакет Python. runner.py — это скрипт, а не модуль.

chepner 19.05.2024 17:40

В чем заключалось сообщение об ошибке? «ModuleNotFoundError: нет модуля с именем «FOO»»?

Peter Mortensen 19.05.2024 17:44

@PeterMortensen «ModuleNotFoundError: нет модуля с именем 'src'», и ошибка была выдана из foo.py из строки from src.constants import SOME_CONST.

Eyal Golan 19.05.2024 19:11
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
5
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы не должны рассматривать 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?

Eyal Golan 19.05.2024 17:42

Кроме того, почему создание venv решило проблему?

Eyal Golan 19.05.2024 17:46

Нет, src должен быть «релевантным» только для вашего исходного репозитория. runner.py можно установить в /usr/bin, а module_a и constants можно установить, например, в /usr/lib/python/site-packages.

chepner 19.05.2024 17:46

Как вы установили код в виртуальную среду?

chepner 19.05.2024 17:47
python -m venv C:\path_to_project\src.
Eyal Golan 19.05.2024 19:20

Это просто создает виртуальную среду с вашим переводчиком в C:\path_to_project\src\bin\python. На самом деле вы вообще не устанавливаете свой код, а создаете вокруг него виртуальную среду. Ни один из ваших кодов не находится в нужном месте.

chepner 19.05.2024 20:57

Я понимаю, но из любопытства - почему устранилась ошибка ModuleNotFound?

Eyal Golan 20.05.2024 14:44

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