从文件夹动态导入所有模块

时间:2017-10-27 17:36:23

标签: python python-3.x import module python-import

我知道有this question,但不仅是他们没有工作,这不完全是我想要的。我正在开发一款赛车游戏,并希望动态加载文件夹中的所有曲目(它们存储为.py而不是.json)。我不想知道曲目的名称,因为用户可以随意修改/添加它们。我只是想导入他们的数据。所以,例如:

>tracks 
>>track0.py
>>track1.py
>>track2.py
>>track3.py
>>track4.py

在每首曲目中,我都有这样的数据:

track_ground_data = [
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1],
    [1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1],
    [1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1],
    [1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1],
    [1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1],
    [1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1],
    [1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1],
    [1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1],
    [1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1],
    [1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1],
    [1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1],
    [1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]

我需要像这样导入每个轨道模块:

loaded_tracks = [t for t in tracks] # Where tracks is the folder.

然后像这样访问给定的track_ground_data

loaded_tracks[0].track_ground_data

如果我知道Python的导入会非常苛刻,我会使用json代替.py。

3 个答案:

答案 0 :(得分:2)

Python 会自动导入包中包含的子模块。 因此,import tracks 加载tracks/__init__.py

但是可以将代码放入导入该目录中找到的所有模块的__init__.py文件中。

例如,在__init__.py

中添加这样的内容
import os
import importlib

__globals = globals()

for file in os.listdir(os.path.dirname(__file__)):
    mod_name = file[:-3]   # strip .py at the end
    __globals[mod_name] = importlib.import_module('.' + mod_name, package=__name__)

仅在导入tracks.trackX时,应使您的子模块可用tracks

或者您可以使用exec

import os
import importlib

for file in os.listdir(os.path.dirname(__file__)):
    mod_name = file[:-3]   # strip .py at the end
    exec('import .' + mod_name)

更简洁的方法是使用导入挂钩或实现您自己的自定义模块导入程序。使用importlib有多种方法可以执行此操作。另请参阅sys.path_hooks

答案 1 :(得分:1)

当框架具有插件或添加系统以供社区贡献时,通常会面临动态导入模块的问题。每个插件或附件都是一个包含符合框架体系结构和API的类和函数的模块。

考虑到这一点,解决了#34;加入点#34;框架代码和任意多个附加组件之间是通过python标准库中的importlib。你似乎面临同样的结构性问题。

以下是使用importlib回答的stackoverflow question。 还有documentation

答案 2 :(得分:1)

为了未来pythoners的良好福利,我发布了我已经解决的问题。一位朋友帮助我度过了难关。 Coudl没有让Bakuriu的解决方案工作,因为模块是空的。在__init__.py里面我放了:

import os

dir = os.path.dirname(os.path.abspath(__file__))
modules = [os.path.splitext(_file)[0] for _file in os.listdir(dir) if not _file.startswith('__')]

tracks = []
for mod in modules:
    exec('from tracks import {}; tracks.append({})'.format(mod, mod))

然后,在主文件上,我将其加载为:

dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(dir)

from tracks import tracks

然后:

loaded_tracks = [t for t in tracks]

实际上解决得很好。我差点切换到JSON /放弃。