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

This recipe will let you import a module from code that is dynamically generated. My original use for it was to import a module stored in a database, but it will work for modules from any source.

Python, 47 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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# Importing a dynamically generated module

def importCode(code,name,add_to_sys_modules=0):
    """
    Import dynamically generated code as a module. code is the
    object containing the code (a string, a file handle or an
    actual compiled code object, same types as accepted by an
    exec statement). The name is the name to give to the module,
    and the final argument says wheter to add it to sys.modules
    or not. If it is added, a subsequent import statement using
    name will return this module. If it is not added to sys.modules
    import will try to load it in the normal fashion.

    import foo

    is equivalent to

    foofile = open("/path/to/foo.py")
    foo = importCode(foofile,"foo",1)

    Returns a newly generated module.
    """
    import sys,imp

    module = imp.new_module(name)

    exec code in module.__dict__
    if add_to_sys_modules:
        sys.modules[name] = module

    return module

# Example
code = \
"""
def testFunc():
    print "spam!"

class testClass:
    def testMethod(self):
        print "eggs!"
"""

m = importCode(code,"test")
m.testFunc()
o = m.testClass()
o.testMethod()

4 comments

Irmen de Jong 19 years, 9 months ago  # | flag

This doesn't work with packages. This obviously doesn't work when you're dealing with packages. For instance, importCode(code,'my.packaged.module') won't work.

Piyush 7 years, 4 months ago  # | flag

Question 1:

what is the meaning of this line, "exec code in module.__dict__", and if I try the syntax as "exec(code in module.__dict__)" it gives me error saying - "TypeError: exec: arg 1 must be a string, file, or code object".

The error is obvious, because "code in module.__dict__" evaluates to false and exec() is expecting a string. And if I do just exec(code), I can't access the class inside my module.

Can you please suggest, how should I write this statement, so that I can make python2 and python3 happy as well as can access the classes inside my module.

Question 2:

When we don't add module to sys.modules, where does the module go?

Thanks in advance.

Piyush 7 years, 4 months ago  # | flag

Got it - this can be modified as - exec( source, module.__dict__). Now, module can be assigned to sys.modules[name] successfully both in python2 and python3.

Peter Sanders 4 years, 12 months ago  # | flag

Can I extend this question? Suppose I have a very small web site written in Python on which client1 accesses POSTform1 which calls myScript1.py to process the returned data. Using the above recipe I add code to the webserver to import myScript1.py, processing of the data proceeds according to plan.

Q1> Can I now unimport/unload/get-rid-of the module created from myScript1.py and reclaim its resources - with the thought in mind that there will finish up being a number of such modules involved with the web server?

Q2> What happens when client2 accesses POSTform1 if myScript1 hasn't been unimported as in Q1? I presume in such circumstance I will have to detect that myScript1.py has previously been imported.

TIA.