Встроенный Python __import__ против imp.load_module: ValueError: Попытка относительного импорта за пределы пакета верхнего уровня

У меня есть кусок кода, который динамически импортирует кучу подпакетов - структура пакета:

main_package/
    code_below_is_here.py
    game/
        __init__.py
        game1/
            __init__.py
            constants.py
            records.py
            ...
        game2/
            __init__.py
            constants.py
            records.py
            ...

с использованием __import__ функция (отказ от ответственности: я не писал этот код, я просто текущий сопровождающий):

import pkgutil
import game as game_init# <----- I import the game/ package
# Detect the known games
for importer,modname,ispkg in pkgutil.iter_modules(game_init.__path__):
    if not ispkg: continue # game support modules are packages
    # Equivalent of "from game import <modname>"
    try:
        module = __import__('game',globals(),locals(),[modname],-1)
    except ImportError:
        continue

Это работает просто отлично.

Теперь я пытался использовать imp.load_module сделать то же самое (пытаясь ответить на другой мой вопрос):

     for importer, modname, ispkg in pkgutil.iter_modules(game_init.__path__):
         if not ispkg: continue # game support modules are packages
         # Equivalent of "from game import <modname>"
+        init_file, pathname, description = imp.find_module(modname, game_init.__path__)
         try:
-            module = __import__('game',globals(),locals(),[modname],-1)
+            module = imp.load_module(modname, init_file, pathname, description)
         except ImportError:
             deprint(u'Error in game support module:', modname, traceback=True)
             continue
+        finally:
+            if init_file is not None: init_file.close()

Но это не так с:

Traceback (most recent call last):
...
  File "C:\Dropbox\eclipse_workspaces\python\wrye-bash\Mopy\bash\bush.py", line 64, in _supportedGames
    module = imp.load_module(modname, init_file, pathname, description)
  File "C:\Dropbox\eclipse_workspaces\python\wrye-bash\Mopy\bash\game\fallout4\__init__.py", line 32, in <module>
    from .records import MreHeader, MreLvli, MreLvln
  File "C:\Dropbox\eclipse_workspaces\python\wrye-bash\Mopy\bash\game\fallout4\records.py", line 26, in <module>
    from ..skyrim.records import MelBounds, MreLeveledList
ValueError: Attempted relative import beyond toplevel package

Я думаю, что ответ где-то в __import__ Документы, где мы читаем:

Функция импортирует имя модуля, потенциально используя данные глобальные и локальные значения, чтобы определить, как интерпретировать имя в контексте пакета. Список from дает имена объектов или подмодулей, которые должны быть импортированы из модуля, заданного именем. Стандартная реализация вообще не использует свой аргумент locals, а использует глобальные переменные только для определения контекста пакета оператора import.

Так:

  • можно ли позвонить imp.load_module с другим набором аргументов, поэтому известно, что пакет верхнего уровня, действительно, не game/gameX?

Связанные с:

0 ответов

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