I would like to import a submodule without knowing its name beforehand,
>>> __import__("os.path")
<module 'os' from '/usr/lib/python3.3/os.py'>
Doesn't work as you might expect, returning os
, not os.path
.
I came up with this solution.
def import_submodule(mod, submod):
ns = {}
exec_str = "from %s import %s as submod" % (mod, submod)
exec(exec_str, ns, ns)
return ns["submod"]
This gives the result:
>>> import_submodule("os", "path")
<module 'posixpath' from '/usr/lib/python3.3/posixpath.py'>
However I would rather not use exec() because its rather bad practice and seems unnecessary when Pythons import mechanisms are available already through __import__
, imp
and importlib
modules.
Is there a way in Python3.x to do this kind of import though a function call, rather then using exec()
?
name.split('.')
, then loop to usegetattr()
to retrieve the 'subobject';.path
in your case. – Smellyos.path
might lead you on a wild goose chase, since it doesn't necessarily work like other modules – Geri__init__.py
file as an example (which is fairly common). The while point of my question is to have this work exactly likefrom A import B as C
. – Garget__import__('parentmodule.submodule')
does importsubmodule
but returnsparentmodule
. – Smellymy_import = lambda mod: (__import__(mod), __import__('sys').modules[mod])[1]
– Garget.
and use everything but the first element in a loop withgetattr()
. – Smellyimportlib
) which isn't cited in the answers to the other question. Marking this as a duplicate might mean that people will still use other home-made solutions instead of the new import machinery. On current versions of python you almost never need to call__import__
directly. – Publishimportlib.import_module()
here. – Smelly