我有一段动态导入大量子包的代码 - 包结构:
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__
的文档中很常见,在那里我们读到:
该函数导入模块名称,可能使用给定的globals和locals来确定如何解释包上下文中的名称。 fromlist给出了应该从name给出的模块导入的对象或子模块的名称。标准实现根本不使用其locals参数,并仅使用其全局变量来确定import语句的包上下文。
所以:
imp.load_module
,以便让它知道顶级包确实不是游戏/ gameX?相关: