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.
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()
|
Tags: sysadmin
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.
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.
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.
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.