Dynamically Import Module From Memory In Python 3 Using Hooks
What I want to achieve is exactly what this this answer proposes, however in Python 3. The code below works fine in Python 2: import sys import imp modules = { 'my_module': '''cla
Solution 1:
The short answer is that you forgot to translate the latter half of the exec
statement from the code sample. That causes the exec
to be applied in
the context of the load_module
method — not the new_module
; so specify the context:
exec(self._modules[fullname], new_module.__dict__)
However, using a Python versioned 3.4 or higher, you become subject to PEP 451 (the introduction of module specs), as well as the deprecation of the imp
module, in favor of importlib
. Particularly:
- The
imp.new_module(name)
function is replaced byimportlib.util.module_from_spec(spec)
. - An abstract base class for meta path finder objects is supplied:
importlib.abc.MetaPathFinder
. - And such finder objects now use
find_spec
rather thanfind_module
.
Here is a very close reimplementation of the code sample.
import importlib
import sys
import types
class StringLoader(importlib.abc.Loader):
def __init__(self, modules):
self._modules = modules
def has_module(self, fullname):
return (fullname in self._modules)
def create_module(self, spec):
if self.has_module(spec.name):
module = types.ModuleType(spec.name)
exec(self._modules[spec.name], module.__dict__)
return module
def exec_module(self, module):
pass
class StringFinder(importlib.abc.MetaPathFinder):
def __init__(self, loader):
self._loader = loader
def find_spec(self, fullname, path, target=None):
if self._loader.has_module(fullname):
return importlib.machinery.ModuleSpec(fullname, self._loader)
if __name__ == '__main__':
modules = {
'my_module': """
BAZ = 42
class Foo:
def __init__(self, *args: str):
self.args = args
def bar(self):
return ', '.join(self.args)
"""}
finder = StringFinder(StringLoader(modules))
sys.meta_path.append(finder)
import my_module
foo = my_module.Foo('Hello', 'World!')
print(foo.bar())
print(my_module.BAZ)
Post a Comment for "Dynamically Import Module From Memory In Python 3 Using Hooks"