Recipe16.3.Importing from a Module Whose Name Is Determined at Runtime


Recipe 16.3. Importing from a Module Whose Name Is Determined at Runtime

Credit: Jürgen Hermann

Problem

You need to import a name from a module, just as from module import name would do, but module and name are runtime-computed expressions. This need often arises, for example, when you want to support user-written plug-ins.

Solution

The _ _import_ _ built-in function lets you perform this task:

def importName(modulename, name):     """ Import a named object from a module in the context of this function.     """     try:         module = _ _import_ _(modulename, globals( ), locals( ), [name])     except ImportError:         return None     return getattr(module, name)

Discussion

This recipe's function lets you perform the equivalent of from module import name, in which either or both module and name are dynamic values (i.e., expressions or variables) rather than constant strings. For example, this functionality can be used to implement a plug-in mechanism to extend an application with external modules that adhere to a common interface.

Some programmers' instinctive reaction to this task would be to use exec, but this instinct would be a pretty bad one. The exec statement is too powerful, and therefore is a last-ditch measure, to be used only when nothing else is available (which is almost never). It's just too easy to have horrid bugs and/or security weaknesses where exec is used. In almost all cases, there are better ways. This recipe shows one such way for an important problem.

For example, suppose you have, in a file named MyApp/extensions/spam.py, the following code:

class Handler(object):     def handleSomething(self):         print "spam!"

and, in a file named MyApp/extensions/eggs.py:

class Handler(object):     def handleSomething(self):         print "eggs!"

We must also suppose that the MyApp directory is in a directory on sys.path, and both it and the extensions subdirectory are identified as Python packages (meaning that each of them must contain a file, possibly empty, named _ _init_ _.py). Then, we can get and call both implementations with the following code:

for extname in 'spam', 'eggs':     HandlerClass = importName("MyApp.extensions." + extname, "Handler")     handler = HandlerClass( )     handler.handleSomething( )

It's possible to remove the constraints about sys.path and _ _init_ _.py, and dynamically import from anywhere, with the imp standard module. However, imp is substantially harder to use than the _ _import_ _ built-in function, and you can generally arrange things to avoid imp's greater generality and difficulty.

The import pattern implemented by this recipe is used in MoinMoin (http://moin.sourceforge.net/) to load extensions implementing variations of a common interface, such as action, macro, and formatter.

See Also

Documentation on the _ _import_ _ and getattr built-ins in the Library Reference and Python in a Nutshell; MoinMoin is available at http://moin.sourceforge.net.



Python Cookbook
Python Cookbook
ISBN: 0596007973
EAN: 2147483647
Year: 2004
Pages: 420

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net