15.3 Importing a Dynamically Generated Module
Credit: Anders Hammarquist
15.3.1 Problem
You have code in either compiled or source form and need to wrap it
in a module, possibly adding it to sys.modules as
well.
15.3.2 Solution
We build a new module object, optionally add it to
sys.modules, and populate it with an
exec statement:
def importCode(code, name, add_to_sys_modules=0):
""" code can be any object containing code -- string, file object, or
compiled code object. Returns a new module object initialized
by dynamically importing the given code and optionally adds it
to sys.modules under the given name.
"""
import imp
module = imp.new_module(name)
if add_to_sys_modules:
import sys
sys.modules[name] = module
exec code in module._ _dict_ _
return module
15.3.3 Discussion
This recipe lets you import a module from code that is dynamically
generated or obtained. My original intent for it was to import a
module stored in a database, but it will work for modules from any
source. Thanks to the flexibility of the exec
statement, the
importCode
function can accept code in many forms: a string of source
(implicitly compiled), a file object (ditto), or a previously
compiled code object, for example.
The addition of the newly generated module to
sys.modules is optional. You
shouldn't normally do this for such dynamically
obtained code, but there are exceptions�for example, when
import statements for the
module's name are later executed, and
it's important that they're
retrieved from sys.modules. Note that if you want
the sys.modules addition, it's
best to perform it before the module's code body
executes, just as normal import statements do, in case the code body
relies on that normal behavior (which it normally
doesn't, but it can't hurt to
prepare for this).
Note that
the normal Python statement:
import foo
is basically equivalent to:
if 'foo' in sys.modules:
foo = sys.modules['foo']
else:
foofile = open("/path/to/foo.py")
foo = importCode(foofile, "foo", 1)
An example of using this recipe:
code = """
def testFunc( ):
print "spam!"
class testClass:
def testMethod(self):
print "eggs!"
"""
m = importCode(code,"test")
m.testFunc( )
o = m.testClass( )
o.testMethod( )
15.3.4 See Also
Sections on the import and exec
statements in the Language Reference;
documentation on the modules attribute of the
sys standard library module and the
imp module in the Library
Reference.
|