How to dynamically load a Python class How to dynamically load a Python class python python

How to dynamically load a Python class


From the python documentation, here's the function you want:

def my_import(name):    components = name.split('.')    mod = __import__(components[0])    for comp in components[1:]:        mod = getattr(mod, comp)    return mod

The reason a simple __import__ won't work is because any import of anything past the first dot in a package string is an attribute of the module you're importing. Thus, something like this won't work:

__import__('foo.bar.baz.qux')

You'd have to call the above function like so:

my_import('foo.bar.baz.qux')

Or in the case of your example:

klass = my_import('my_package.my_module.my_class')some_object = klass()

EDIT: I was a bit off on this. What you're basically wanting to do is this:

from my_package.my_module import my_class

The above function is only necessary if you have a empty fromlist. Thus, the appropriate call would be like this:

mod = __import__('my_package.my_module', fromlist=['my_class'])klass = getattr(mod, 'my_class')


If you don't want to roll your own, there is a function available in the pydoc module that does exactly this:

from pydoc import locatemy_class = locate('my_package.my_module.MyClass')

The advantage of this approach over the others listed here is that locate will find any python object at the provided dotted path, not just an object directly within a module. e.g. my_package.my_module.MyClass.attr.

If you're curious what their recipe is, here's the function:

def locate(path, forceload=0):    """Locate an object by name or dotted path, importing as necessary."""    parts = [part for part in split(path, '.') if part]    module, n = None, 0    while n < len(parts):        nextmodule = safeimport(join(parts[:n+1], '.'), forceload)        if nextmodule: module, n = nextmodule, n + 1        else: break    if module:        object = module    else:        object = __builtin__    for part in parts[n:]:        try:            object = getattr(object, part)        except AttributeError:            return None    return object

It relies on pydoc.safeimport function. Here are the docs for that:

"""Import a module; handle errors; return None if the module isn't found.If the module *is* found but an exception occurs, it's wrapped in anErrorDuringImport exception and reraised.  Unlike __import__, if apackage path is specified, the module at the end of the path is returned,not the package at the beginning.  If the optional 'forceload' argumentis 1, we reload the module from disk (unless it's a dynamic extension)."""


import importlibmodule = importlib.import_module('my_package.my_module')my_class = getattr(module, 'MyClass')my_instance = my_class()