Если ваш модуль верхнего уровня не является файлом, но упакован как каталог с помощью __init__.py, то принятое решение почти работает, но не совсем. В Python 3.5+ необходим следующий код (обратите внимание на добавленную строку, начинающуюся с 'sys.modules'):
MODULE_PATH = "/path/to/your/module/__init__.py"
MODULE_NAME = "mymodule"
import importlib
import sys
spec = importlib.util.spec_from_file_location(MODULE_NAME, MODULE_PATH)
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module
spec.loader.exec_module(module)
Без этой строки при выполнении exec_module он пытается привязать относительный импорт в вашем верхнем уровне __init__.py к имени модуля верхнего уровня - в данном случае «mymodule». Но «mymodule» еще не загружен, поэтому вы получите ошибку «SystemError: Родительский модуль« mymodule »не загружен, не может выполнить относительный импорт». Поэтому вам нужно привязать имя, прежде чем загружать его. Причиной этого является фундаментальный инвариант системы относительного импорта: «Инвариантное удержание заключается в том, что если у вас есть sys.modules ['spam'] и sys.modules ['spam.foo'] (как вы сделали бы после вышеупомянутого импорта ), последний должен появляться как атрибут foo предыдущего ", как обсуждено здесь .