21

In python you can do something like this to import a module using a string filename, and assign its namespace a variable on the local namespace.

x = __import__(str)

I'm wondering if there is a related function that will take take a string of Python code, instead of a path to a file with Python code, and return its namespace as a variable.

For example,

str = "a = 5";
x = importstr(str)
print x.a
#output is 5

I realize that I could write the string to a file, then use __import__ on it, but I'd like to skip the intermediate file if possible.

The reason for this is that I'm experimenting with metaprogramming in python, and it seems like a good solution to what I'm doing.

Mike
  • 58,961
  • 76
  • 175
  • 221

5 Answers5

15

Here's an example of dynamically creating module objects using the imp module

Jeremy Brown
  • 17,880
  • 4
  • 35
  • 28
7

Unfortunately, the imp module was recently deprecated (I have NO idea why).

Instead, you should do this:

from types import ModuleType
import sys

mod = ModuleType('my_module', 'doc string here')
exec('a = 1', mod.__dict__)
print(mod.a) # prints 1
# add to sys.modules
sys.modules['my_module'] = mod

Or you can use PyExt's RuntimeModule.from_string:

from pyext import RuntimeModule

mod = RuntimeModule.from_string('a = 1')
print(mod.a) # 1
kirbyfan64sos
  • 10,377
  • 6
  • 54
  • 75
6

Here is how to import a string as a module:

import sys,imp

my_code = 'a = 5'
mymodule = imp.new_module('mymodule')
exec my_code in mymodule.__dict__    

so you can now access the module attributes (and functions, classes etc) as:

mymodule.a
>>> 5

To ignore any next attempt to import, add the module to sys:

sys.modules['mymodule'] = mymodule
Remi
  • 20,619
  • 8
  • 57
  • 41
5

types.ModuleType is not recommended according to Python documentation on module_from_spec():

importlib.util.module_from_spec(spec)

...

This function is preferred over using types.ModuleType to create a new module as spec is used to set as many import-controlled attributes on the module as possible.

Here is what I came up with to load the module from source code.

import importlib.util
spec = importlib.util.spec_from_loader('helper', loader=None)
helper = importlib.util.module_from_spec(spec)
exec('a = 5', helper.__dict__)

print(type(helper)) # prints "<class 'module'>"
helper.a # prints "5"
Community
  • 1
  • 1
LVitya
  • 528
  • 4
  • 11
2

Is this something what you're looking for ?

my_namespace = {}
exec "a = 5" in my_namespace
print my_namespace["a"]
Tarantula
  • 19,031
  • 12
  • 54
  • 71