Python импорт, когда скрипты запускаются из другой папки (предка) - PullRequest
1 голос
/ 08 мая 2020

У меня есть большой репозиторий с фиксированной структурой, и я расширил его несколькими папками и python скриптами, чтобы добавить к нему дополнительные функции в целом. Структура выглядит следующим образом:

  • toplevelfolder
    • featureA
      • someModuleA.py
      • __ init __. Py
    • featureB
      • someModuleB.py
      • __ init __. Py
    • приложение
    • __ init __.py
    • app.py

Теперь someModuleA.py и someModuleB.py могут быть вызваны через app.py, но в то же время могут быть вызывается напрямую, однако этот вызов должен исходить из папки верхнего уровня для правильного разрешения относительных путей в файле, то есть через python ./featureA/someModuleA.py.

Все это работает хорошо, но теперь мне нужны некоторые определения функций из someModuleB в someModuleA и, следовательно, я хочу импортировать этот модуль. Я пробовал как абсолютный, так и относительный импорт, но оба терпят неудачу с разными ошибками, абсолютный импорт с

from toplevelfolder.featureA import someModuleA as A

# ModuleNotFoundError: No module named 'toplevelfolder'

и относительный импорт с

from toplevelfolder.featureA import someModuleA as A

# ImportError: attempted relative import with no known parent package

Теперь я вижу, что относительный import вызовет проблемы, когда python вызывается из toplevelfolder, поскольку .. будет представлять родительский каталог последнего, а не родительский каталог featureA. Однако я не могу уловить первое сообщение об ошибке, тем более что toplevelfolder должен быть не модулем, а пакетом.

Есть ли другой способ импорта в Python, о котором я не знаю, если возможно без изменения PYTHONPATH, sys.path или чего-то подобного?

Ответы [ 2 ]

1 голос
/ 09 мая 2020

Не уверен на 100%, какова здесь цель. Мой совет:

  1. Четко определите, какими должны быть ваши модули и пакеты верхнего уровня.

  2. Сделайте весь импорт абсолютным.

  3. Либо:

    • сделайте ваш проект настоящим устанавливаемым проектом, чтобы эти модули и пакеты верхнего уровня были установлены в каталоге site-packages среды;
    • или убедитесь, что текущий рабочий каталог - это тот, который содержит модули и пакеты верхнего уровня.
  4. Обязательно вызовите свой код через исполняемый модуль или метод package вместо метода script , если « точка входа », которую вы хотите выполнить, является частью пакета

    • DO ( исполняемый модуль или пакет ):
      • path/to/pythonX.Y -m toplevelpackage.module
      • path/to/pythonX.Y -m toplevelpackage.subpackage (при наличии файла toplevelpackage/subpackage/__main__.py)
    • НЕ ( сценарий в пакете):
      • path/to/pythonX.Y toplevelpackage/module.py
    * 1 059 *
  5. (Необязательно) Позже, когда все будет хорошо работать и все будет под контролем, вы можете решить изменить некоторые или все операции импорта на относительные. (Если все будет сделано правильно, я считаю, что можно было бы сделать это так, чтобы можно было вызывать исполняемые модули с любого уровня в структуре каталогов как текущий рабочий каталог.)

Ссылки:

0 голосов
/ 08 мая 2020

Попробуйте вставить это выше вашего импорта:

import os,sys,inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0,parentdir) 

Тогда вы сможете импортировать файл из родительской папки.

...