I encounted something strange about python import statement.
Let's say that I have a file structure like below:
foo\
__init__.py
bar.py
os.py
Codes in bar.py (Other files are empty)
import os
print os.__file__
The strange thing is when I run python -m foo.bar
, it prints
foo/os.pyc
However, when I changed direcotry to foo
, and run python -m bar
, it prints
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc
What's the difference between the two ways I run script?
In a word, what's the order Python used to import module?
From official documents, I found several text about this problem (They made me even more confused)
the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path.
the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter. If the script directory is not available (e.g. if the interpreter is invoked interactively or if the script is read from standard input), path[0] is the empty string, which directs Python to search modules in the current directory first.
In fact, such references are so common that the import statement first looks in the containing package before looking in the standard module search path.
...
If the imported module is not found in the current package (the package of which the current module is a submodule), the import statement looks for a top-level module with the given name.
Imports should be grouped in the following order: Standard library imports. Related third party imports. Local application/library specific imports.
Importing Modules To make use of the functions in a module, you'll need to import the module with an import statement. An import statement is made up of the import keyword along with the name of the module. In a Python file, this will be declared at the top of the code, under any shebang lines or general comments.
Import order does not matter. If a module relies on other modules, it needs to import them itself. Python treats each . py file as a self-contained unit as far as what's visible in that file.
You need to use the import keyword along with the desired module name. When interpreter comes across an import statement, it imports the module to your current program. You can use the functions inside a module by using a dot(.) operator along with the module name.
What's the difference between the two ways I run script?
The difference is if foo
is (from python's view) a loaded module or not.
If you run python -m foo.bar
, foo
is a valid module. Even with Python 2.7, import os
is still a relative import and hence os
gets resolved against the containing module (i.e. foo
), first:
https://docs.python.org/2/tutorial/modules.html#intra-package-references:
The submodules often need to refer to each other. For example, the surround module might use the echo module. In fact, such references are so common that the import statement first looks in the containing package before looking in the standard module search path.
When you run python -m bar
, bar
is a top level module, i.e. it has no containing module. In that case import os
goes to through sys.path
.
The default module search for an import bla
is
sys.path
and use the first successful import.To disable (1), you can
from __future__ import absolute_import
at the very top of a module.
Confusing? Absolutely.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With