【问题标题】:Calling a particular function for every module in a python directory为 python 目录中的每个模块调用特定函数
【发布时间】:2018-07-19 22:29:17
【问题描述】:

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

我的文件结构如下: -运行.py -/板 -Brd1.py -Brd2.py -Brd3.py

我想要完成的是为 board 目录中的每个模块调用“运行”函数。每个模块都有这个“运行”功能。这是我在 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' 对象没有属性 '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)

只打印: ['__ 文档 __', '__ 名称 __', '__ 包 __ ']

还有什么可以做我想要完成的事情吗?我要马上解决这个问题吗?

【问题讨论】:

  • “堆栈溢出的答案都没有帮助我解决这个问题”并没有真正帮助我们。你看了哪些问题和答案?他们怎么没有帮助?

标签: python file import module


【解决方案1】:

这可能对您不起作用,因为正如 abarnert 指出的那样,您只是在加载一个空模块。另外,查看您的文件结构,您需要插入板文件夹的路径名:

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()

【讨论】:

    【解决方案2】:

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

    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
    

    【讨论】:

    • 这不起作用。我得到一个 ImportError: No module named Brd1
    • @kaaazemian“我得到一个 ImportError”不是可以调试的东西。您尝试了以上三个选项中的哪一个?你的代码是什么样的?异常从何而来?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多