在Python中动态导入类

时间:2012-11-14 16:14:27

标签: python

我想从给定的字符串动态加载一个类。但是,我不知道该类将在哪个文件中,因此我将不得不搜索所有文件。我试过这个,但是我得到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'

3 个答案:

答案 0 :(得分: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.pybar.py位于同一目录中:

#foo.py
class foo(object):
    pass

#bar.py
class qux(object):
    pass

答案 1 :(得分:1)

根据documentation new_module返回和模块:

  

imp.new_module(名称)
      返回名为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>

答案 2 :(得分:0)

按照imp documentation中的示例:

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

def myFunction():
        return "Hello World!"

动态导入你好(没有最后的尝试):

fp, pathname, description = imp.find_module("hello")
hello = imp.load_module("hello", fp, pathname, description)
hello.myFunction() # returns 'Hello World!'