Reputation: 6794
I am trying to understand the package and module name shadowing rules in python and stumbled across a case where I do not understand why the results that I see make any sense. This cases happens for python 2 (with from future import absolute_imports
) and python 3.
Assuming I have the following folder structure:
├── mypackage
│ ├── argparse.py
│ └── __init__.py
└── script.py
mypackage
is my custom top-level package, where I have a module shadowing the standard argparse
module. Inside my script I execute the following code:
import argparse
print(argparse)
from mypackage.argparse import foo
print(argparse)
The results are the ones I expect:
<module 'argparse' from '/usr/lib/python3.5/argparse.py'>
<module 'argparse' from '/usr/lib/python3.5/argparse.py'>
However, if I change my script to execute a function from my package and execute the same import and print statements in the __init__.py
of my package, i.e.:
script:
from mypackage import main
main()
__init__.py
:
import argparse
print(argparse)
from mypackage.argparse import foo
print(argparse)
def main():
pass
As a result I see:
<module 'argparse' from '/usr/lib/python3.5/argparse.py'>
<module 'mypackage.argparse' from '/tmp/test/src/mypackage/argparse.py'>
Why does in this case (and not in the other one) the from X import Y
statement override the previous global import of argparse
to the local module?
Upvotes: 3
Views: 99
Reputation: 21474
Consider how you access submodules, you would write mypackage.argparse
to access the submodule of mypackage
.
Now consider how attribute lookup for modules work, it searches for the attribute in the modules global namespace.
Putting these two together, the only way to access submodules is by adding them to the packages global namespace, this is the intended behaviour.
Upvotes: 1