没有一个关于堆栈溢出的答案能帮助我解决这个问题:Load module from string in python
我的文件结构如下:-run.py -/boards -Brd1.py -Brd2.py -Brd3.py
我想要完成的是为boards目录中的每个模块调用"run“函数。每个模块都有这个"run“功能。下面是我在run.py中的代码:
import os
import sys,imp
import inspect
for item in os.listdir("boards"):
if item.startswith("Brd") and item.endswith(".py"):
curr_module = imp.new_module(item)
curr_module.run()
这是我得到的错误:
运行模块:“
”对象没有“AttributeError”属性“”
但是,当我显式地这样做时:
from boards import Brd1
Brd1.run()
它工作得很完美。有趣的是,代码如下:
import os
import sys,imp
import inspect
for item in os.listdir("boards"):
if item.startswith("Brd") and item.endswith(".py"):
curr_module = imp.new_module(item)
print dir(curr_module)
只打印:'__文档__ ','__ name __ ',‘__ package __’
有没有办法去做我想要完成的事情呢?我现在就开始做这件事吗?
发布于 2018-07-21 02:54:03
这可能对你不起作用,因为正如abarnert指出的那样,你只加载了一个空模块。另外,查看您的文件结构,您需要插入boards文件夹的路径名:
sys.path.insert(0, './boards')
只需使用导入内部的python文档即可解决您正在尝试的问题:https://docs.python.org/2/library/imp.html#imp.get_suffixes
我刚刚测试了它,这段代码完全符合您的要求:
for item in os.listdir("boards"):
if item.startswith("Brd") and item.endswith(".py"):
name = os.path.splitext(item)[0]
fp, pathname, description = imp.find_module(name)
with open(pathname) as f:
curr_module = imp.load_module(name, fp, pathname, description)
curr_module.run()
发布于 2018-07-20 06:52:50
您不需要做任何事情来加载模块,您只是创建和运行空模块。
curr_module = imp.new_module(item)
curr_module.run()
来自the docs的评论:
imp.new_module
(名称)
返回一个名为name的新的空模块对象。此对象未插入到sys.modules中。
所以,这实际上和你写的代码是一样的:
curr_module = types.ModuleType(item)
curr_module.run()
你得到['__ doc __ ', ' __ name __ ', '__ package __ ']
的原因(尽管我非常确定你实际上得到的是没有那些额外空格的['__doc__ ', '__name__', '__package__']
)是因为这些属性即使在一个空的模块上也存在。
您复制此代码的示例代码正在尝试做一些完全不同的事情。这个问题的重点是如何从一串源代码中创建一个模块,而不是通常的方式。这是通过创建一个新的空模块,然后对该模块的全局变量执行exec
来实现的(在2.x中)。exec
是模块最终不为空的原因,而您没有做任何类似的事情。
您还为模块指定了一个无效的名称,比如用Brd1.py
代替Brd1
。
如果您想实际加载模块,请查看Examples
fp, pathname, description = imp.find_module(name)
curr_module = imp.load_module(name, fp, pathname, description)
# …
当然你不想通过普通的搜索来加载它,而是通过路径名来加载。您可以将path
参数传递给find_module
name = os.path.splitext(item)[0]
fp, pathname, description = imp.find_module(name, 'boards')
…或者直接加载:
name = os.path.splitext(item)[0]
pathname = os.path.join("boards", item)
desc = [s for s in imp.get_suffixes if s[0] == '.py']
with open(pathname) as f:
curr_module = imp.load_module(name, f, pathname, desc)
您可能还希望将模块放在sys.modules
中。或者你可能不会。(该示例没有这样做,因为它模拟了__import__
函数的效果。)如果是这样的话:
sys.modules[name] = curr_module
您可能还希望执行sys.modules
检查,如示例中所示。如果执行检查,则尝试导入同一文件两次将在第二次使用缓存版本,就像执行普通import
一样;如果不执行检查,则类似于调用reload
try:
curr_module = sys.modules[name]
except KeyError:
# the logic above to find and load curr_module
https://stackoverflow.com/questions/51432562
复制相似问题