Reputation: 60771
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.
Upvotes: 21
Views: 12623
Reputation: 567
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"
Upvotes: 6
Reputation: 10727
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
Upvotes: 8
Reputation: 21175
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
Upvotes: 6
Reputation: 18318
Here's an example of dynamically creating module objects using the imp module
Upvotes: 15
Reputation: 19862
Is this something what you're looking for ?
my_namespace = {}
exec "a = 5" in my_namespace
print my_namespace["a"]
Upvotes: 2