Python | __ init__. Detailed explanation of Py action

Reproduced at: https://www.cnblogs.com/tp1226/p/8453854.html

\[QAQ \]

We often see the file "_init_. Py" in the module directory of python, so what is its function?

1. Identify that the directory is a python module package

If you use python's IDE for development, if the file exists in the directory, the directory will be recognized as module package.

2. Simplify module import operation

Suppose the directory structure of our module package is as follows:

.
└── mypackage
    ├── subpackage_1
    │   ├── test11.py
    │   └── test12.py
    ├── subpackage_2
    │   ├── test21.py
    │   └── test22.py
    └── subpackage_3
        ├── test31.py
        └── test32.py

If we use the most direct import method, copy the whole file to the project directory, and then import it directly:

from mypackage.subpackage_1 import test11
from mypackage.subpackage_1 import test12
from mypackage.subpackage_2 import test21
from mypackage.subpackage_2 import test22
from mypackage.subpackage_3 import test31
from mypackage.subpackage_3 import test32

Of course, there are few files in this example. If the module is large and the directory is deep, you may not remember how to import it. (it is very likely that even if you want to import only one module, you have to look in the directory for a long time)

In this case, init.py is very useful. Let's first look at how the file works.

2.1 how does init.py work?

In fact, if the directory contains__ init__.py, when importing the directory with import, the__ init__.py inside the code.

We add one in the mypackage directory__ init__.py file to do an experiment:

.
└── mypackage
    ├── __init__.py
    ├── subpackage_1
    │   ├── test11.py
    │   └── test12.py
    ├── subpackage_2
    │   ├── test21.py
    │   └── test22.py
    └── subpackage_3
        ├── test31.py
        └── test32.py

Add a print in mypackage/init.py. If the file is executed, it will output:

print("You have imported mypackage")

Next, import directly in interactive mode

>>> import mypackage
You have imported mypackage

Obviously, init.py is executed when the package is imported.

2.2 control module import

Let's do another experiment and add the following statement in mypackage/init.py:

from subpackage_1 import test11

Let's try importing mypackage:

>>> import mypackage
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/taopeng/Workspace/Test/mypackage/__init__.py", line 2, in <module>
    from subpackage_1 import test11
ImportError: No module named 'subpackage_1'

Wrong report... What's going on?
Originally, when we execute import, the current directory will not change (even if it is a file executing a subdirectory), but we still need a complete package name.

from mypackage.subpackage_1 import test11

To sum up, we can specify the modules to be imported by default in init.py

2.3 lazy introduction method

Sometimes when we import, we will be lazy and import all the contents in the package

from mypackage import *

How did this happen__ all__ That's what variables do.
 __ all__ A module list is associated. When from xx import * is executed, the modules in the list will be imported. We will__ init__.py is modified to:

__all__ = ['subpackage_1', 'subpackage_2']

Subpackage is not included here_ 3. To prove__ all__ Works instead of importing all subdirectories.

>>> from mypackage import *
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'subpackage_1', 'subpackage_2']
>>> 
>>> dir(subpackage_1)
['__doc__', '__loader__', '__name__', '__package__', '__path__', '__spec__']

Modules in subdirectory are not imported!!!

The import in this example is equivalent to: from mypackage import subpackage_ 1, subpackage_ two

Therefore, the import operation continues to look for subpackages_ 1 and subpackage_2__ init__.py and execute. (however, import * will not be executed at this time.)

We are in the subpackage_ Add under 1__ init__.py file:

__all__ = ['test11', 'test12']

# By default, only test11 is imported
from mypackage.subpackage_1 import test11

Try importing again

>>> from mypackage import *
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'subpackage_1', 'subpackage_2']
>>> 
>>> dir(subpackage_1)
['__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'test11']

If you want to import all modules of a sub package, you need to specify them more precisely.

>>> from mypackage.subpackage_1 import *
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'test11', 'test12']

3. Initialization of configuration module

I understand__ init__. After the working principle of python, you should understand that the file is a normal Python code file.
Therefore, you can put the initialization code into this file.

Posted by Forever_xxl on Tue, 09 Nov 2021 00:16:11 -0800