How to load a module from code in a string?
Here is how to import a string as a module (Python 2.x):
import sys,imp
my_code = 'a = 5'
mymodule = imp.new_module('mymodule')
exec my_code in mymodule.__dict__
In Python 3, exec is a function, so this should work:
import sys,imp
my_code = 'a = 5'
mymodule = imp.new_module('mymodule')
exec(my_code, mymodule.__dict__)
Now access the module attributes (and functions, classes etc) as:
print(mymodule.a)
>>> 5
To ignore any next attempt to import, add the module to sys
:
sys.modules['mymodule'] = mymodule
Load module from python string without executing code
The process of importing a module requires that its code be executed. The interpreter creates a new namespace and populates it by executing the module's code with the new namespace as the global namespace, after which you can access those values (remember that the def
and class
statements are executable).
So maybe you will have to educate your users not to write modules that interact with the IDE?
How can I import a module dynamically given its name as string?
With Python older than 2.7/3.1, that's pretty much how you do it.
For newer versions, see importlib.import_module
for Python 2 and Python 3.
You can use exec
if you want to as well.
Or using __import__
you can import a list of modules by doing this:
>>> moduleNames = ['sys', 'os', 're', 'unittest']
>>> moduleNames
['sys', 'os', 're', 'unittest']
>>> modules = map(__import__, moduleNames)
Ripped straight from Dive Into Python.
Python: Dynamically import module's code from string with importlib
You can simply instantiate types.Module
:
import types
mod = types.ModuleType("mod")
Then you can populate it with exec
just like you did:
exec(code, mod.__dict__)
mod.testFunc() # will print 'spam!'
So your code will look like this:
import types
def import_code(code, name):
# create blank module
module = types.ModuleType(name)
# populate the module with code
exec(code, module.__dict__)
return module
code = """
def testFunc():
print('spam!')
"""
m = import_code(code, 'test')
m.testFunc()
As commented by @Error - Syntactical Remorse, you should keep in mind that exec
basically executes whatever code is contained in the string you give it, so you should use it with extra care.
At least check what you're given, but it'd be good to use exclusively predefined strings.
How do I load a Python module from a string while preserving debug?
Here's how to define a loader that takes the module's source from a string, and then creates and loads the module into sys.modules
. It could be useful if the module's source is not in a file. If there is already a file then use https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly
Although inspect.getsource(module)
works for a subclass of importlib.abc.InspectLoader
for which it would only be necessary to define get_source
, tracebacks and pdb
don't appear to be willing to display the source code until you inherit from SourceLoader
.
import sys
import importlib.abc, importlib.util
class StringLoader(importlib.abc.SourceLoader):
def __init__(self, data):
self.data = data
def get_source(self, fullname):
return self.data
def get_source(self, fullname):
return self.data
def get_data(self, path):
return self.data.encode("utf-8")
def get_filename(self, fullname):
return "<not a real path>/" + fullname + ".py"
module_name = "testmodule"
with open("testmodule.py", "r") as module:
loader = StringLoader(module.read())
spec = importlib.util.spec_from_loader(module_name, loader, origin="built-in")
module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module
spec.loader.exec_module(module)
import module from string variable
The __import__
function can be a bit hard to understand.
If you change
i = __import__('matplotlib.text')
to
i = __import__('matplotlib.text', fromlist=[''])
then i
will refer to matplotlib.text
.
In Python 3.1 or later, you can use importlib
:
import importlib
i = importlib.import_module("matplotlib.text")
Some notes
If you're trying to import something from a sub-folder e.g.
./feature/email.py
, the code will look likeimportlib.import_module("feature.email")
Before Python 3.3 you could not import anything if there was no
__init__.py
in the folder with file you were trying to import (see caveats before deciding if you want to keep the file for backward compatibility e.g. withpytest
).
Load node.js module from string in memory
function requireFromString(src, filename) {
var Module = module.constructor;
var m = new Module();
m._compile(src, filename);
return m.exports;
}
console.log(requireFromString('module.exports = { test: 1}', ''));
look at _compile, _extensions and _load in module.js
Related Topics
Plotting a Decision Boundary Separating 2 Classes Using Matplotlib's Pyplot
What Is the Return Value of Os.System() in Python
Reversing a Regular Expression in Python
When Are Parentheses Required Around a Tuple
Execute Terminal Command from Python in New Terminal Window
Prepend a Line to an Existing File in Python
Trying to Import Module with the Same Name as a Built-In Module Causes an Import Error
Saving a Figure After Invoking Pyplot.Show() Results in an Empty File
How to Filter Rows in Pandas by Regex
Scrolling to Element Using Webdriver
How to Find Most Common Elements of a List
Filling in Login Forms in Instagram Using Selenium and Webdriver (Chrome) Python Osx
Appending a Dictionary to a List - I See a Pointer Like Behavior
How to Add Multiple Values to a Dictionary Key
Share Large, Read-Only Numpy Array Between Multiprocessing Processes