I was surprised to find out that both the two call in main.py
works:
import package_top
package_top.module.hello() # I thought this won't work ...
package_top.hello() # I thought this is the only way
package_top
package_top/
├── __init__.py
└── module.py
__init__.py
from .module import hello
module.py
def hello():
print("module_hello")
From my understanding, when I call import package_top
in main.py
, it will run __init__.py
which adds hello to namespace package_top, and then package_top is added to namespace main, so I can access hello with package_top.hello()
. What I don't understand is why the second call also works?
I expect the prgram to throw out an error at the second line.
The Python import machinery modifies the package_top
module object and adds the module
attribute as part of importing the child module. See the Python import docs on submodules:
When a submodule is loaded using any mechanism (e.g. importlib APIs, the import or import-from statements, or built-in
__import__()
) a binding is placed in the parent module’s namespace to the submodule object.
Other import statements such as from other_package import x, y
only add the x
and y
names to the importing module object. In your case, from .module import hello
, is both importing the function hello
, and also importing the submodule module
of package_top
, so your import statement creates both package_top.hello
and package_top.module
, which in turn gives you access to package_top.module.hello
.
You can confirm this by printing the module scope after importing:
from .module import hello
print(dir())
prints:
['__builtins__', (more default __stuff__ ...), 'hello', 'module']
Therefor package_top.module.hello()
works without problems. Remove the from .module import hello
statement and you will see the submodule is not imported, and the package_top.module.hello()
statement will fail.