Credit: Jürgen Hermann
You
need to import a name from a module, such as from
module
import
name
, but
module
and name
are runtime-computed expressions. This need often arises, for example
when you want to support user-written plug-ins.
The _ _import_ _
built-in function allows this:
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 vars(module)[name]
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 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 a last-ditch
measure, to be used only when nothing else is available (which is
basically 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 the
MyApp/extensions/spam.py
file:
class Handler: def handleSomething(self): print "spam!"
and in the MyApp/extensions/eggs.py
file:
class Handler: def handleSomething(self): print "eggs!"
then as long as the MyApp
directory is on
sys.path
, and both it and the
extensions
directory are identified as packages
by containing a file named _ _init_ _.py
, we can
get and call both implementations with this 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, this is substantially harder to use than
the _ _import_ _
built-in function, and you can
generally arrange things to avoid
imp
’s generality and difficulty.
This pattern is used in MoinMoin (http://moin.sourceforge.net/) to load extensions implementing variations of a common interface, such as “action”, “macro”, and “formatter”.
Documentation on the _ _import_ _
and
vars
built-ins in the Library Reference; MoinMoin is available at http://moin.sourceforge.net.
Get Python Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.