1

我想从给定的字符串动态加载一个类。但是,我不知道该类将在哪个文件中,所以我必须搜索所有文件。我已经尝试过了,但AttributeError: 'module' object has no attribute 'MyClass'即使我 100% 确定该模块(在当前迭代中)具有该类,我也得到了:

target = 'MyClass'
module_names = [mf[0:-3] for mf in os.listdir('application/models') if mf.endswith(".py")]
modules = [imp.new_module(x) for x in module_names]
for module in modules:
    try:
        target_class = getattr(module, target)
    except ImportError, AttributeError:
        continue

if target_class:
    print 'found class'

看来我真的很接近了。我想要的不是将搜索限制在一个文件夹中,而可能是多个文件夹。我的代码有什么问题?

编辑:好的,现在我正在尝试这样的事情,但仍然遇到同样的错误:

    for m in module_names:
        try:
            x = reload(__import__(m))
            target_class = getattr(x, target)
        except ImportError, AttributeError:
            continue
        else:
            break

    if target_class:
        print 'found class'
4

3 回答 3

2

从文档上看imp.new_module,返回的模块是的。这意味着它永远不会包含您的课程。

也许您想要做的是将您的目标目录添加到sys.path并用于__import__动态导入这些模块,然后检查您的类?


以下代码适用于我:

modules = ['foo','bar']
for mod in modules:
    try:
        x = reload(__import__(mod))
    except ImportError:
        print "bargh! import error!"
        continue
    try:
        cls = getattr(x,'qux')
    except AttributeError:
        continue

a = cls()
print a.__class__.__name__

在同一目录中的位置foo.py和位置:bar.py

#foo.py
class foo(object):
    pass

和:

#bar.py
class qux(object):
    pass
于 2012-11-14T16:20:59.850 回答
1

根据文档 new_module返回和模块:

imp.new_module(name)
返回一个名为 name 的新空模块对象。此对象未插入 sys.modules。

您可能想查看imp.load_source。这只是一个简单的例子:

class Test:
    pass

In [19]: m = imp.load_source("test", "./test.py")
In [20]: getattr(m, "Test")
Out[20]: <class test.Test at 0x1fe6120>
于 2012-11-14T16:20:57.580 回答
0

按照imp 文档中的示例:

名为 hello.py 的同一目录中的文件:

def myFunction():
        return "Hello World!"

动态导入 hello (w/o try except finally):

fp, pathname, description = imp.find_module("hello")
hello = imp.load_module("hello", fp, pathname, description)
hello.myFunction() # returns 'Hello World!'
于 2015-02-23T16:28:51.063 回答