Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate a module object from a code object in Python

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__
like image 468
Tac-Tics Avatar asked Feb 22 '10 23:02

Tac-Tics


People also ask

Can you create a module in Python?

Some modules are available through the Python Standard Library and are therefore installed with your Python installation. Others can be installed with Python's package manager pip . Additionally, you can create your own Python modules since modules are comprised of Python . py files.

What is __ module __ in Python?

The __module__ property is intended for retrieving the module where the function was defined, either to read the source code or sometimes to re-import it in a script.

How do you see the code behind a module in Python?

We use the getsource() method of inspect module to get the source code of the function. Returns the text of the source code for an object. The argument may be a module, class, method, function, traceback, frame, or code object. The source code is returned as a single string.


1 Answers

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.

like image 109
Alex Martelli Avatar answered Oct 22 '22 08:10

Alex Martelli