关于堆栈溢出的答案都没有帮助我解决这个问题: Load module from string in python
我的文件结构如下: -run.py -/板 -Brd1.py -Brd2.py -Brd3.py
我要完成的工作是为boards目录中的每个模块调用“运行”功能。每个模块都具有此“运行”功能。这是我在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)
仅打印: ['__ doc __','__ name __','__ package __']
反正有做我想完成的事情吗?我马上就去解决吗?
答案 0 :(得分:1)
您没有做任何事情来加载模块,只是创建并运行空模块。
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__']
没有所有这些多余的空格)是因为这些属性即使在空模块中也存在。
您从中复制此示例代码的示例试图做一些完全不同的事情。这个问题的全部要点是如何用一串源代码创建模块,而不是通常的方法。您将执行以下操作(在2.x中):创建一个新的空模块,然后对模块的全局变量执行exec
。 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
答案 1 :(得分:1)
这可能对您不起作用,因为正如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()