首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为python目录中的每个模块调用特定函数

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

Stack Overflow用户
提问于 2018-07-20 06:29:18
回答 2查看 63关注 0票数 2

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

我的文件结构如下:-run.py -/boards -Brd1.py -Brd2.py -Brd3.py

我想要完成的是为boards目录中的每个模块调用"run“函数。每个模块都有这个"run“功能。下面是我在run.py中的代码:

代码语言:javascript
复制
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”属性“”

但是,当我显式地这样做时:

代码语言:javascript
复制
from boards import Brd1

Brd1.run()

它工作得很完美。有趣的是,代码如下:

代码语言:javascript
复制
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 __’

有没有办法去做我想要完成的事情呢?我现在就开始做这件事吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-21 02:54:03

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

代码语言:javascript
复制
sys.path.insert(0, './boards')

只需使用导入内部的python文档即可解决您正在尝试的问题:https://docs.python.org/2/library/imp.html#imp.get_suffixes

我刚刚测试了它,这段代码完全符合您的要求:

代码语言:javascript
复制
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()
票数 1
EN

Stack Overflow用户

发布于 2018-07-20 06:52:50

您不需要做任何事情来加载模块,您只是创建和运行空模块。

代码语言:javascript
复制
curr_module = imp.new_module(item)
curr_module.run()

来自the docs的评论:

imp.new_module(名称)

返回一个名为name的新的空模块对象。此对象未插入到sys.modules中。

所以,这实际上和你写的代码是一样的:

代码语言:javascript
复制
curr_module = types.ModuleType(item)
curr_module.run()

你得到['__ doc __ ', ' __ name __ ', '__ package __ ']的原因(尽管我非常确定你实际上得到的是没有那些额外空格的['__doc__ ', '__name__', '__package__'] )是因为这些属性即使在一个空的模块上也存在。

您复制此代码的示例代码正在尝试做一些完全不同的事情。这个问题的重点是如何从一串源代码中创建一个模块,而不是通常的方式。这是通过创建一个新的空模块,然后对该模块的全局变量执行exec来实现的(在2.x中)。exec是模块最终不为空的原因,而您没有做任何类似的事情。

您还为模块指定了一个无效的名称,比如用Brd1.py代替Brd1

如果您想实际加载模块,请查看Examples

代码语言:javascript
复制
fp, pathname, description = imp.find_module(name)
curr_module = imp.load_module(name, fp, pathname, description)
# …

当然你不想通过普通的搜索来加载它,而是通过路径名来加载。您可以将path参数传递给find_module

代码语言:javascript
复制
name = os.path.splitext(item)[0]
fp, pathname, description = imp.find_module(name, 'boards')

…或者直接加载:

代码语言:javascript
复制
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__函数的效果。)如果是这样的话:

代码语言:javascript
复制
sys.modules[name] = curr_module

您可能还希望执行sys.modules检查,如示例中所示。如果执行检查,则尝试导入同一文件两次将在第二次使用缓存版本,就像执行普通import一样;如果不执行检查,则类似于调用reload

代码语言:javascript
复制
try:
    curr_module = sys.modules[name]
except KeyError:
    # the logic above to find and load curr_module
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51432562

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档