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

Python 从文件夹中动态导入所有模块,python,python-3.x,import,module,python-import,Python,Python 3.x,Import,Module,Python Import,我知道有,但他们不仅没有工作,这也不是我想要的。我正在开发一款赛车游戏,希望动态加载文件夹中的所有曲目(它们存储为.py而不是.json)。我不想知道这些曲目的名称,因为用户可以随意修改/添加它们。我只想导入他们的数据。例如: >tracks >>track0.py >>track1.py >>track2.py >>track3.py >>track4.py 在每首曲目中,我都有如下数据: track_ground_data

我知道有,但他们不仅没有工作,这也不是我想要的。我正在开发一款赛车游戏,希望动态加载文件夹中的所有曲目(它们存储为.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.
loaded_tracks[0].track_ground_data
我需要像这样导入每个轨迹模块:

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.
loaded_tracks[0].track_ground_data
然后访问给定的
轨道地面数据
,如下所示:

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.
loaded_tracks[0].track_ground_data
如果我知道Python对导入的要求如此苛刻,我会使用json代替.py。

Python不会自动导入包中包含的子模块。 因此
仅导入曲目
加载
曲目/\uuuu init\uuuu.py

但是,您可以将代码放在导入在该目录中找到的所有模块的
\uuuu init\uuuu.py
文件中

例如,在
\uuuu init\uuuu.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__)
仅导入
曲目时,应使子模块可用作
曲目.trackX

或者您可以使用
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)

更干净的方法是使用导入挂钩或实现您自己的自定义模块导入器。有多种方法可以使用see实现这一点。Python不会自动导入包中包含的子模块。 因此
仅导入曲目
加载
曲目/\uuuu init\uuuu.py

但是,您可以将代码放在导入在该目录中找到的所有模块的
\uuuu init\uuuu.py
文件中

例如,在
\uuuu init\uuuu.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__)
仅导入
曲目时,应使子模块可用作
曲目.trackX

或者您可以使用
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)


更干净的方法是使用导入挂钩或实现您自己的自定义模块导入器。使用see也有多种方法来实现这一点。当框架有插件或附加系统供社区贡献时,通常会遇到动态导入模块的问题。每个插件或附加组件都是一个模块,包含符合框架架构和api的类和函数

考虑到这一点,在框架代码和任意多个附加组件之间“连接点”的解决方案是通过python标准库中提供的
importlib
。你似乎面临着同样的结构性问题

下面是一个stackoverflow,其回答为
importlib

当框架有插件或附加系统供社区贡献时,通常会遇到动态导入模块的问题。每个插件或附加组件都是一个模块,包含符合框架架构和api的类和函数

考虑到这一点,在框架代码和任意多个附加组件之间“连接点”的解决方案是通过python标准库中提供的
importlib
。你似乎面临着同样的结构性问题

下面是一个stackoverflow,其回答为
importlib

还有。

为了未来蟒蛇爱好者的健康,我在这里发布我是如何解决的。一个朋友帮我度过了难关。无法使Bakuriu的解决方案工作,因为模块是空的。在
\uuuu init\uuuuu.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/放弃了。

为了未来pythonners的良好发展,我正在发布我是如何解决的。一个朋友帮我度过了难关。无法使Bakuriu的解决方案工作,因为模块是空的。在
\uuuu init\uuuuu.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/放弃了。

是的。我已将该代码放在一个
\uuuu init\uuuuuuuy.py
文件中,当我尝试导入一个曲目(
导入曲目
):
tracks.track0
,我会得到一个
AttributeError
。没错,您可能应该使用为存储数据而设计的文件格式,而不是可执行的.py文件…您可以通过适应有关包的相关问题来做到这一点。如果轨道只包含静态数据,则使用python文件是无用的。然而,他们允许放置任意代码,这可能是一个功能。。。例如,一些轨迹可以定义一些函数,为特定轨迹提供特定的逻辑,而使用简单的json就很难做到这一点。如果您不需要灵活性,只需使用json文件(顺便说一句:您仍然可以使用自定义模块加载器将它们作为python模块导入…)是的。我已将该代码放在一个
\uuuu init\uuuuuuuy.py
文件中,当我尝试导入一个曲目(
导入曲目
):
tracks.track0
,我会得到一个
AttributeError
。没错,您可能应该使用为存储数据而设计的文件格式,而不是可执行的.py文件…您可以通过适应有关包的相关问题来做到这一点。如果轨道只包含静态数据,则使用python文件是无用的。然而,他们允许放置任意代码,这可能是一个功能。。。例如,一些轨迹可以定义一些函数,为特定轨迹提供特定的逻辑,而使用简单的json就很难做到这一点。如果您不需要灵活性,只需使用json文件(顺便说一句:您仍然可以使用自定义模块加载器将它们作为python模块导入…)您还需要过滤掉
\uuuuuu init\uuuuuuuuuuuy.py
,因此只有在
mod\u name
与模式不匹配时才执行最后一条语句。类似于
if not re.match(r'^\uuuuu',file):
。您还需要过滤掉
\uuuuuu init\uuuuuuuuuy.py
,所以只需要