Build classes/packages dinamicaly

Peter Otten __peter__ at web.de
Tue Dec 16 08:01:43 EST 2003


Paulo Pinto wrote:

> Thanks it is want I was looking for.
> However I still have a problem.
> 
> I want to make the module available to the
> caller as if he did an import.
> 
> For example, if I make the following call
> 
> some_module.generate_module('dummy')
> 
> Where some_module is the module that generates
> modules dinamicaly, and dummy is the name of the
> new module.
> 
> I would like to be able to do
> 
> dummy.something()
> 
> after that call.
> 
> I've discovered that if I do something like this
> 
> globals()['dummy'] = module_instance_returned_by_new.module()
> 
> 
> It works, but it must be done at the same level I want to
> call dummy.something() and not from inside some_module. Because
> if I do it inside the module, globals() will be refering to the
> module globals and not to parent scope.
> 
> Basically I would like to import the generated module to the
> module that is invoking generate_module() like an uplevel in
> Tcl.
> 
> Is this possible?

Don't know, but rebinding in the calling scope from inside a function call
looks like fighting the language to me. Maybe redefining __import__() would
be better:

<myimport.py>
import __builtin__
import types, sys

originalimport = __builtin__.__import__

def myimport(name, *args):
    print "importing", name
    try:
        return originalimport(name, *args)
    except ImportError:
        print "generating", name
        module = types.ModuleType(name)
        exec "def demo(*args):\n\tprint 'demo%r' % (args,)\n" in
module.__dict__
        sys.modules[name] = module # put it into the cache
        return module

__builtin__.__import__ = myimport
</myimport.py>

I simply generate any module that cannot successfully be imported, but you
could change this to meet your needs. Now a usage example:

<usemyimport.py>
import myimport # put it first, because it messes with the built-ins

print "first import"
import os
import generated
print
print "second import"
import os, generated

generated.demo("hi", "there")
</usemyimport.py>

However, this is just a smoother variant of the

module = generate("modulename")

pattern.

Peter




More information about the Python-list mailing list