Python, import string of Python code as module
Asked Answered
W

5

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.

Wilkie answered 1/9, 2010 at 1:56 Comment(0)
P
15

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

Prittleprattle answered 1/9, 2010 at 2:2 Comment(3)
hrm... got my first ever downvote with this answer and I'm not sure why??Prittleprattle
@JeremyBrown just the thing I was hunting for. As I up voted it, consider the down vote undone ;)Seamanship
Please copy the essential answer information from your external links into the answer body. So if and when the remote site ever moves the content or goes down, the solution is not lost.Robespierre
A
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
Afterthought answered 11/2, 2015 at 18:31 Comment(1)
I know this is really late, but are there any advantages of solution above the other?Empyreal
E
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
Erfert answered 15/9, 2011 at 20:7 Comment(0)
C
6

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"
Credible answered 4/2, 2020 at 9:28 Comment(0)
S
2

Is this something what you're looking for ?

my_namespace = {}
exec "a = 5" in my_namespace
print my_namespace["a"]
Spaniel answered 1/9, 2010 at 2:0 Comment(1)
i'd prefer not to need to refer to the namespace items using a stringWilkie

© 2022 - 2024 — McMap. All rights reserved.