views:

115

answers:

1

Given that I have the code object for a module, how do I get the corresponding module object?

It looks like moduleNames = {}; exec code in moduleNames does something very close to what I want. It returns the globals declared in the module into a dictionary. But if I want the actual module object, how do I get it?

EDIT: It looks like you can roll your own module object. The module type isn't conveniently documented, but you can do something like this:

import sys
module = sys.__class__
del sys
foo = module('foo', 'Doc string')
foo.__file__ = 'foo.pyc'
exec code in foo.__dict__
+4  A: 

As a comment already indicates, in today's Python the preferred way to instantiate types that don't have built-in names is to call the type obtained via the types module from the standard library:

>>> import types
>>> m = types.ModuleType('m', 'The m module')

note that this does not automatically insert the new module in sys.modules:

>>> import sys
>>> sys.modules['m']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'm'

That's a task you must perform by hand:

>>> sys.modules['m'] = m
>>> sys.modules['m']
<module 'm' (built-in)>

This can be important, since a module's code object normally executes after the module's added to sys.modules -- for example, it's perfectly correct for such code to refer to sys.modules[__name__], and that would fail (KeyError) if you forgot this step. After this step, and setting m.__file__ as you already have in your edit,

>>> code = compile("a=23", "m.py", "exec")
>>> exec code in m.__dict__
>>> m.a
23

(or the Python 3 equivalent where exec is a function, if Python 3 is what you're using, of course;-) is correct (of course, you'll normally have obtained the code object by subtler means than compiling a string, but that's not material to your question;-).

In older versions of Python you would have used the new module instead of the types module to make a new module object at the start, but new is deprecated since Python 2.6 and removed in Python 3.

Alex Martelli