I have been trying to use importlib
with python3 (3.6).
Directory structure
main.py
#Note: I will only modify line 4 that uses importlib
import importlib
if __name__ == '__main__':
print("In main.py")
hello = importlib.import_module('hello', package='./')
print("Loaded hello.py")
hello.hello()
hello.py
def hello():
print('Hello world')
folder/hello.py
def hello():
print('Hello world in folder')
Observations
If I do
hello = importlib.import_module('hello', package='./')
or
hello = importlib.import_module('hello')
It imports hello.py from the root folder and prints hello world
.
If I do
hello = importlib.import_module('folder.hello')
It imports folder/hello.py from the root folder and prints hello world in folder
.
But if I do
hello = importlib.import_module('hello', package='folder')
or
hello = importlib.import_module('hello', package='./folder')
It gives error
Traceback (most recent call last):
File "main.py", line 4, in <module>
hello = importlib.import_module('hello', package='./folder')
File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'hello'
Problem
I am not sure what is going on here. I am pretty sure there is something wrong with my understanding of python modules and packages. Can someone explain why this is the expected behavior?
If the first argument, the module to be imported is an absolute module reference ( has no leading .
), the seond argument is completely ignored.
To import a module a
relative to another module b
, you have to use
a = importlib.import_module('.a', package='b')
In your case, this should work
hello = importlib.import_module('.hello', package='folder')
As a rule of thumb, import package
should work if you want to use package
as second argument.
from package import module
then becomes
importlib.import_module(module, package)