为python目录中的每个模块调用特定功能

时间:2018-07-19 22:29:18

标签: python file import module

关于堆栈溢出的答案都没有帮助我解决这个问题: 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 __']

反正有做我想完成的事情吗?我马上就去解决吗?

2 个答案:

答案 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中):创建一个新的空模块,然后对模块的全局变量执行execexec是导致模块最终不为空且您未执行任何类似操作的原因。


您还为模块指定了无效的名称,例如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()