Recipe16.2.Importing a Dynamically Generated Module


Recipe 16.2. Importing a Dynamically Generated Module

Credit: Anders Hammarquist

Problem

You need to wrap code in either compiled or source form in a module, possibly adding it to sys.modules as well.

Solution

We build a new module object, optionally add it to sys.modules, and populate it with an exec statement:

import new def importCode(code, name, add_to_sys_modules=False):     """ code can be any object containing code: a string, a file object, or         a 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.     """     module = new.module(name)     if add_to_sys_modules:         import sys         sys.modules[name] = module     exec code in module._ _dict_ _     return module

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 (which gets implicitly compiled on the fly), a file object (ditto), or a previously compiled code object.

The addition of the newly generated module to sys.modules is optional. You shouldn't normally do so for such dynamically obtained code, but there are exceptionsspecifically, when import statements for the module's name are later executed, and it's important that they retrieve from sys.modules your dynamically generated module. 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 usually doesn't, but it can't hurt to be prepared).

Note that the normal Python statement:

import foo

in simple cases (where no hooks, built-in modules, imports from zip files, etc., come into play!) is essentially equivalent to:

if 'foo' in sys.modules:     foo = sys.modules['foo'] else:     foofile = open("/path/to/foo.py")      # for some suitable /path/to/...     foo = importCode(foofile, "foo", 1)

A toy example of using this recipe:

code = """ def testFunc( ):     print "spam!" class testClass(object):     def testMethod(self):         print "eggs!" """ m = importCode(code, "test") m.testFunc( ) o = m.testClass( ) o.testMethod( )

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 new module in the Library Reference; Python in a Nutshell sections about both the language and library aspects.



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