How to Load a Module from Code in a String

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 like importlib.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. with pytest).

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



Leave a reply



Submit