Почему при импорте из командной строки происходит сбой при импорте, а при запуске из PyCharm импорт выполняется успешно? - PullRequest
1 голос
/ 29 января 2020

Я получаю "ModuleNotFoundError: Нет модуля с именем"

Небольшой фон:

1) Мой venv использует python 3.6.9

2) Уже пробовал добавление папок в PYTHONPATH через sys.path.append

3) Heirarchy или соответствующую часть:

/ папка проекта

| - папка A

  |--__init__.py
  |--a.py

| - папка B

  |--__init__.py
  |--b.py

| - init .py

Я пытаюсь импортировать из .py to b.py Пробовал по-разному -

1) импорт b

2) из ​​b import x

Был бы очень признателен за помощь, был на этом для какое-то время.

1 Ответ

2 голосов
/ 29 января 2020

Why?

Потому что вы запускаете скрипт по-другому. Когда вы запускаете его с PyCharm, PyCharm добавляет каталог проекта и все исходные каталоги в sys.path. Вот почему import A.a работает. Однако, когда вы запускаете ваш скрипт с консольной командой, к sys.path добавляется только местоположение файла. Просто напечатайте sys.path, чтобы увидеть, что в нем содержится.

Для решения этой проблемы вы можете использовать различные подходы.

Самый простой способ - использовать PYTHONPATH. Например, на Windows вы можете запустить команду set PYTHONPATH=[project_folder];%PYTHONPATH%, тогда import A.a работает. Или вы можете запустить немного другую версию set PYTHONPATH=[project_folder/A];%PYTHONPATH%, тогда import a работает. По сути, эта команда добавляет каталог в sys.path.

Альтернативное решение - использовать функцию main в b.py и некоторые launching_script.py в project_folder. Вместо запуска b.py вы запускаете launching_script.py. Таким образом, у вас всегда есть каталог проекта в sys.path. Поэтому абсолютный импорт, начинающийся с каталога проекта (например, import A.a), будет работать как в PyCharm, так и в консоли.

Другой подход - это некрасивый код, подобный следующему:

try:
    import A.a as module_a
except ModuleNotFoundError:
    import pathlib
    import sys
    sys.path.append(str(pathlib.Path(__file__).parent.parent))
    import A.a as module_a

Также вы можете использовать относительный импорт. Немного сложнее, менее читабельным и подверженным ошибкам способом, требующим некоторой работы над структурой проекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...