I want to import a module programmatically given a string representation of the module. I can do this with:
>>> import importlib
>>> m = importlib.import_module('some.path.module')
>>> m.greet('bob')
Hello, bob
However, the location I have is actually a variable defined as a path, either relative or absolute, along with a second variable for the filename. So it would be in this case:
path = 'some/path'
file = 'module.py'
I cannot use os.path.join(path, file)
, as this results in some/path/module.py
, which is not valid input to importlib.import_module
.
I could use os.path.join(path, file).replace('/', '.').replace('.py', '')
, which would give 'some.path.module'
, but this gives problems when using absolute paths that begin with a slash for example, like /home/me/code/importing/some/path/module.py
-> .home.me.code.importing.some.path.module
- we would need to use os.path.join(path, file).replace('/', '.').replace('.py', '').lstrip('.')
. Not only is that a bit ugly, I'm not actually sure if it is appropriate to use importlib to import in that way anyway - the dots in home.me.code.importing.some.path.module
suggest that any one of those levels could be a subpackage with valid python code, as this is how it would appear if importing directly. For example, it implies that we might import it like:
from home.me.code.importing.some.path import module
suggesting that this is just a nested package within the home
package which is obviously not correct.
Is there a robust way to do this? Ideally I want to do this without installing other dependencies. Also, I would like to understand if there would be any unexpected issues about importing with a path in such a way.