special case loading modules with imp
Irmen de Jong
irmen at -NOSPAM-REMOVETHIS-xs4all.nl
Wed Jul 30 18:41:15 EDT 2003
Steven Taschuk wrote:
> I was going to suggest StringIO, but it turns out imp.load_module
> wants a real file, not merely something file-like.
>
> However, you can always do it by hand:
>
> >>> import imp
> >>> sourcecode = 'def foo(x): return 11*x'
> >>> mod = imp.new_module('foo')
> >>> exec sourcecode in mod.__dict__
> >>> mod.foo(16)
> 176
Heh, that's cool.
That looks like what I'm doing in Pyro to load (and import)
'mobile code' that is sent from one computer to another.
However I do it a bit different, partly because it's not always
the *source* that gets loaded: if the .pyc bytecodes are available,
those are loaded instead. Also, I stuff the modules into sys.modules
because they have to be found by regular import statements after
they're loaded.
So I'm doing:
--------- code snippet from Pyro ------------
name="not.yet.existing.module"
module=<received module source or .pyc bytecode>
import imp,marshal,new
name=name.split('.')
path=''
mod=new.module("pyro-agent-context")
for m in name:
path+='.'+m
# use already loaded modules instead of overwriting them
real_path = path[1:]
if sys.modules.has_key(real_path):
mod = sys.modules[real_path]
else:
setattr(mod,m,new.module(path[1:]))
mod=getattr(mod,m)
sys.modules[path[1:]]=mod
if module[0:4]!=imp.get_magic():
# compile source code
code=compile(module,'<downloaded>','exec')
else:
# read bytecode from the client
code=marshal.loads(module[8:])
# finally, execute the module code in the right module.
exec code in mod.__dict__
--------- end code snippet from Pyro ------------
It works, but I'm not too fond of the bytecode 'tricks'...
--Irmen
More information about the Python-list
mailing list