Welcome, guest | Sign In | My Account | Store | Cart

This function allows you to do "from module import name", where both "module" and "name" are dynamic values (i.e. expressions or variables). For example, this can be used to implement a "plugin" mechanism to extend an application by external modules that adhere to some common interface.

This pattern is used in MoinMoin (http://moin.sourceforge.net/) to load extensions implementing variations of a common interface, like "action", "macro", and "formatter".

Python, 28 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def importName(modulename, name):
    """ Import a named object from a module in the context of this function,
        which means you should use fully qualified module paths.

        Return None on failure.
    """
    try:
        module = __import__(modulename, globals(), locals(), [name])
    except ImportError:
        return None
        
    return vars(module)[name]

### MyApp/extensions/spam.py
class Handler:
    def handleSomething(self):
        print "spam!"

### MyApp/extensions/eggs.py
class Handler:
    def handleSomething(self):
        print "eggs!"

### Example
extension_name = "spam" # could be "eggs", too!
Handler = importName("MyApp.extensions." + extension_name, "Handler")
handler = Handler()
handler.handleSomething()

3 comments

Chris Green 19 years, 11 months ago  # | flag

Don't forget to have __init__.py. Since this module uses a __import__ call, the extensions folder will have to have an __init__.py in it so that python treats the directory as module path.

Walter Brunswick 18 years, 4 months ago  # | flag

Improve it. Could you perhaps expand this recipe to allow either all, or multiple/selected names to be imported, for example,

importModule('module',('*'))

to import all names, and

importModule('module',('func','func2','func3','class'))

to import selected names.

Also, it would be nice if the names did not have to be assigned manually, i.e., instead of

func, func2, func3, class = importModule('module',('func','func2','func3','class'))

one could do, for instance, simply

importModule('module',('func','func2','func3','class'))

and 'func', 'func2', 'func3', and 'class' would all be imported as attributes of 'module'.

Thanks.

Walter Brunswick 18 years, 4 months ago  # | flag

hmm, no, wait...

If the second argument is NOT given it should just import module with all the attributes: 'module.func', 'module.func2', 'module.func3', 'module.class', and if the second argument IS given, it should import all the names into the global scope: 'func', 'func2', 'func3', 'class'.

Created by Jürgen Hermann on Thu, 15 Mar 2001 (PSF)
Python recipes (4591)
Jürgen Hermann's recipes (14)

Required Modules

  • (none specified)

Other Information and Tasks