Как мне импортировать удаленный модуль, который импортирует локальный модуль?

Моя программа импортирует модуль из другого места, используя importlib.
Этот импортированный модуль (назовем его A) импортирует какой-то другой пользовательский модуль, расположенный рядом с ним (назовем его B). ).

My_Project\
    │
    └─── my_program.py

Some_Other_Location\
    │
    ├─── A_module_my_program_wants_to_import.py
    └─── B_module_A_imports.py

Когда я импортирую A без импорта B, все работает нормально:

# Sample from my_program.py

path = Some_Other_Location\A_module_my_program_wants_to_import.py
spec = importlib.util.spec_from_file_location("A", path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)

Однако, когда в A я импортирую B:

# Sample from A_module_my_program_wants_to_import.py

import B_module_A_imports

Or

from B_module_A_imports import foo

И я запускаю свою программу, я получаю:

Build error: No module named 'B_module_A_imports'
И трассировка до того места, куда я импортирую в своей программе, и A

Я пытался указать submodule_search_locations=Some_Other_Location из spec_from_file_location, но это не помогло.

Итак, вопрос в том, как мне импортировать удаленный модуль, который импортирует локальный модуль?


person tituszban    schedule 03.09.2019    source источник
comment
Мне кажется циклический импорт, так ли это?   -  person geckos    schedule 03.09.2019
comment
Нет. Это порядок импорта: my_program -> A -> B. Ни A, ни B не имеют ничего общего с my_program, а B не зависит от A.   -  person tituszban    schedule 03.09.2019


Ответы (1)


Я нашел обходной путь, но не правильное решение. Обходной путь выглядит следующим образом:

Я понял, что он пытается загрузить B, где находится my_program, и, очевидно, ничего не нашел. Однако можно обмануть загрузчик, чтобы найти файл, добавив Some_Other_Location к sys.path. Вот как выглядит часть импорта my_program:

directory = Some_Other_Location
sys.path.append(directory)

path = Some_Other_Location\A_module_my_program_wants_to_import.py
spec = importlib.util.spec_from_file_location("A", path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)

sys.path.remove(directory)

Это прекрасно работает, однако я по-прежнему открыт для реальных решений!

person tituszban    schedule 04.09.2019