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_specrather thanfind_module.
Here is a very close reimplementation of the code sample.
import importlib
import sys
import types
classStringLoader(importlib.abc.Loader):
def__init__(self, modules):
self._modules = modules
defhas_module(self, fullname):
return (fullname in self._modules)
defcreate_module(self, spec):
if self.has_module(spec.name):
module = types.ModuleType(spec.name)
exec(self._modules[spec.name], module.__dict__)
return module
defexec_module(self, module):
passclassStringFinder(importlib.abc.MetaPathFinder):
def__init__(self, loader):
self._loader = loader
deffind_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"