为python目录中的每个模块调用特定函数

2024-04-26 23:38:37 发布

您现在位置:Python中文网/ 问答频道 /正文

关于堆栈溢出的所有答案都没有帮助我解决这个问题: Load module from string in python

我的文件结构如下: -运行.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: 'module' object has no attribute 'run'

但是,当我明确地做这样的事情时:

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)

仅打印: ['.'文件','.'名称','.'包装']

我要做的事还有什么要做的吗?我是不是马上就去?你知道吗


Tags: 模块文件runinfrompyimportos
2条回答

你没有做任何事情来加载模块,你只是创建和运行空模块。你知道吗

curr_module = imp.new_module(item)
curr_module.run()

来自the docs说:

imp.new_module(name)

Return a new empty module object called name. This object is not inserted in 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

这可能对您不起作用,因为正如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()

相关问题 更多 >