从文件夹动态导入所有模块
Importing dynamically all modules from a folder
我知道有 this question,但它们不仅不起作用,而且也不是我想要的。我正在开发一款赛车游戏,想从一个文件夹中动态加载所有曲目(它们存储为 .py 而不是 .json)。我不想知道曲目名称,因为用户可以随意mod/add。我只想导入他们的数据。所以,例如:
>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。
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
.
时,应该使您的子模块可用 tracks.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)
更简洁的方法是使用导入挂钩或实现您自己的自定义模块导入器。使用 importlib
see also sys.path_hooks
有多种方法可以做到这一点
当框架有插件或附加系统供社区贡献时,通常会面临动态导入模块的问题。每个插件或附加组件都是一个模块,包含 类 和符合框架架构和 api.
的功能
考虑到这一点,"joining the dots" 框架代码和任意多个附加组件之间的解决方案是通过 python 标准库中的 importlib
。你似乎面临同样的结构性问题。
这是一个用 importlib
回答的计算器 question。
还有 documentation.
为了未来的 pythoners 的福祉,我发布了我是如何解决的。一个朋友帮我解决了。无法使 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 / 放弃。
我知道有 this question,但它们不仅不起作用,而且也不是我想要的。我正在开发一款赛车游戏,想从一个文件夹中动态加载所有曲目(它们存储为 .py 而不是 .json)。我不想知道曲目名称,因为用户可以随意mod/add。我只想导入他们的数据。所以,例如:
>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。
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
.
tracks.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)
更简洁的方法是使用导入挂钩或实现您自己的自定义模块导入器。使用 importlib
see also sys.path_hooks
当框架有插件或附加系统供社区贡献时,通常会面临动态导入模块的问题。每个插件或附加组件都是一个模块,包含 类 和符合框架架构和 api.
的功能考虑到这一点,"joining the dots" 框架代码和任意多个附加组件之间的解决方案是通过 python 标准库中的 importlib
。你似乎面临同样的结构性问题。
这是一个用 importlib
回答的计算器 question。
还有 documentation.
为了未来的 pythoners 的福祉,我发布了我是如何解决的。一个朋友帮我解决了。无法使 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 / 放弃。