Modules and Packages
Before you know import, there are two concepts to mention:
- Module: A
.py
file is a module
- Package: The
__init__.py
directory where the file is located is the package
Of course, this is only a minimalist version of the concept. The package is actually a special module, and any module that defines the property is treated as a __path__
package. However, we do not need to know this in our daily use.
Two types of import
import
There are two kinds of forms:
import ...
from ... import ...
There is a very small difference between the two, first look at a few lines of code.
from Import Ascii_lowercase Import string Import String.ascii_lowercase
Run to find the last line of code error: ImportError: No module named ascii_lowercase
, meaning: "Can not find the module called Ascii_lowercase." The difference between lines 1th and 3rd is only that there is no from
, the rollover grammar definition finds that there are rules:
import ...
Only modules or packages can be followed
from ... import ...
from
can only be a module or package, import
followed by any variable
Can be simple to remember: The first empty can only fill the module or package, the second empty fill anything.
Search Path for import
Question, what is the output of the following lines of code?
Import string Print (string.ascii_lowercase)
Is it a lowercase letter? That's not necessarily the case if the directory tree is:
./├──foo.py└──string.py
foo.py
The directory has a string.py
file called, the result is not sure. Because you don't know if it's an import string
import ./string.py
or a standard library string
. In order to answer this question, we need to understand how import found the module, this process is relatively simple, only two steps:
- Search for "built-in Modules" (built-in module)
sys.path
paths in the search
sys.path
when initialized, the following paths are added in order:
- The directory in which it is
foo.py
located (if it is a soft link, it is the real foo.py
directory) or the current directory ;
- Environment Variables
PYTHONPATH
The directories listed in (similar environment variables PATH
, defined by the user, are empty by default);
- The path 1 added when the
site
module is import ( site
will be automatically import at run time).
import site
The path you add is usually XXX/site-packages
(Ubuntu XXX/dist-packages
), like on my machine /usr/local/lib/python2.7/site-packages
. At the same time, the pip
installed package is also stored in this directory. If you don't bother remembering sys.path
the initialization process, you can simply assume that the import's lookup order is:
- Built-in Modules
.py
directory where the files are located
pip
Or easy_install
packages that are installed
Relative import vs. absolute import
When the size of the project becomes larger and the complexity of the code increases, we usually organize a single .py
file into a package that makes the project more structured. There are some problems with import, such as: The directory structure of a typical package is this:
string/__init__. py├──find.py└──foo.py
If string/foo.py
the code is as follows:
# string/foo.py from Import Find Print (Find)
python string/foo.py
which of the following would be the result of the operation?
<module ‘string.find‘ from ‘string/find.py‘>
<function find at 0x123456789>
This is inferred from the various rules we have described earlier, because the directory in which it is foo.py
located string/
does not have a string
module (that is string.py
), so the import is the standard library string
, and the answer is the latter. However, if you foo
run the string
module as a package, you will find that the python -m string.foo
result is the former. The same statement, but there are two different semantics, which undoubtedly adds to our mental burden, not every time we debug the module in the package, we have to check the execution of the command is it python string/foo.py
python -m string.foo
?
The relative import is specifically designed to resolve "in-Package import" (Intra-package import). It's also very simple to use, from
followed by a .
line:
# From string/import find.py from Import Find # From string/find.py Import * from Import *
Let's look at a more complex example of a package with a directory structure that looks like this:
one/__init__. Py├──foo.py└──two/ __init__. py ├──bar.py └──three/ __init__. py ├──dull.py └── run.py
from Import Dull from Import Bar from Import Foo Print ('go, go, go! ')
Change into
from Import *fromimport *fromimport *print('go, go, Go! ')
The result is the same.
So python string/foo.py
python -m string.foo
What is the result of the operation? Run the discovery, the output of the two are:
Traceback (most recent): " string/foo.py " in <module> from importimport in Non-package
' String.find ' from ' string/find.py '>
The reason is that as python string/foo.py
foo.py
a separate script to run, think foo.py
does not belong to any package, so at this time relative import will be error. That is, no matter what the command line is, the semantics of import at run time are unified, and there is no longer any inconsistency in running results.
Import mechanism for Python