Встроенный 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?
Связанные с: