Import class dynamically in Python
Question: I want to dynamically load a class from a given string. However, I do not know
which file the class will be in, so I will have to search all files. I've
tried this, but I get `AttributeError: 'module' object has no attribute
'MyClass'` even though I'm 100% sure that that module (in the current
iteration) has that class:

    
    
    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'
    

It seems I'm getting really close. What I want is not to limit the search to
just one folder, but perhaps multiple folders. What's wrong with my code?

Edit: Ok now I'm trying something like this, but still getting the same error:

    
    
        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'
    


Answer: From the documentation on
[`imp.new_module`](http://docs.python.org/2/library/imp.html#imp.new_module),
the returned module is **empty**. Meaning that it will never contain your
class.

Perhaps what you want to do is add your target directory to `sys.path` and use
`__import__` to dynamically import those modules, then check for your class?

* * *

The following code works for me:

    
    
    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__
    

Where `foo.py` and `bar.py` are in the same directory:

    
    
    #foo.py
    class foo(object):
        pass
    

and:

    
    
    #bar.py
    class qux(object):
        pass
    

