How can I mimic Python's "import .. as" with code from a text string
Question:
I have a text string, code, containing the complete code for a python module. I know I could write the code to a local file and import it as cm with the following:
with open("codemod.py","w") as f:
f.write(code)
import codemod as cm
Is there a way do this directly from the code string without creating a local file? Perhaps using importlib
or __import()__
or exec()
?
I know that exec(code)
has the same effect as import codemod
, but how do I mimic the import as cm
option?
Answers:
You can use exec to execute the code in the string:
# Read file
with open('codemod.py', 'r') as f:
code = f.read()
# Execute code
exec(code)
However, as you’ve already noticed, this will be running the code in the current namespace and not import it as a module but simply execute it.
If you want to have the code to be imported as a module, you need to create the module by hand and add it to the current namespace yourself:
# Read file
with open('codemod.py', 'r') as f:
code = f.read()
import importlib.util as importutil
# Name of module
# Create a new spec for our module
codemod_spec = importutil.spec_from_loader("codemod", loader=None)
# Create a new module codemod
codemod_module = importlib.utils.module_from_spec(codemod_spec)
# Execute the code in the codemod's namespace
exec(code, codemod_module)
# Add module to namespace as 'cm' instead of 'codemod'
globals()['cm'] = codemod_module
# And from now on out you should be all set
I can suggest you to first replace the name "codemod" and then apply exec:
exec(code.replace("codemod","cm"))
But it may rename other functions or variables with "codemod" in their name.
I have a text string, code, containing the complete code for a python module. I know I could write the code to a local file and import it as cm with the following:
with open("codemod.py","w") as f:
f.write(code)
import codemod as cm
Is there a way do this directly from the code string without creating a local file? Perhaps using importlib
or __import()__
or exec()
?
I know that exec(code)
has the same effect as import codemod
, but how do I mimic the import as cm
option?
You can use exec to execute the code in the string:
# Read file
with open('codemod.py', 'r') as f:
code = f.read()
# Execute code
exec(code)
However, as you’ve already noticed, this will be running the code in the current namespace and not import it as a module but simply execute it.
If you want to have the code to be imported as a module, you need to create the module by hand and add it to the current namespace yourself:
# Read file
with open('codemod.py', 'r') as f:
code = f.read()
import importlib.util as importutil
# Name of module
# Create a new spec for our module
codemod_spec = importutil.spec_from_loader("codemod", loader=None)
# Create a new module codemod
codemod_module = importlib.utils.module_from_spec(codemod_spec)
# Execute the code in the codemod's namespace
exec(code, codemod_module)
# Add module to namespace as 'cm' instead of 'codemod'
globals()['cm'] = codemod_module
# And from now on out you should be all set
I can suggest you to first replace the name "codemod" and then apply exec:
exec(code.replace("codemod","cm"))
But it may rename other functions or variables with "codemod" in their name.