The role of "init". Py in python

Keywords: Python

We often see the "init. Py" file in python's module directory, so what's the purpose of it?

 

1. Identify that the directory is a module package of python.

If you are using 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 that 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 entire 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. (most likely, even if you want to import only one module, you have to find it in the directory for a long time.)

In this case, init. Py works. Let's first see how the document works.

2.1 how does init. Py work?

In fact, if the directory contains "init. Py", the code in "init. Py" will be executed when importing the directory with import.

Let's add a "init. Py" file in the mypackage directory 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 /. 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 import 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?

It turns out that when we execute import, the current directory will not change (even if it is a file executing a subdirectory), or we 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 import method

Sometimes when we import, we will be lazy and import everything in the package.

from mypackage import *

How is this achieved? __all variables do the job.

all is associated with a list of modules. When you execute from xx import *, the modules in the list will be imported. Let's change "init". Py "to.

__all__ = ['subpackage_1', 'subpackage_2']

Subpackage 3 is not included here to prove that 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__']

Module in subdirectory is not imported!!!

The import in this example is equivalent to

from mypackage import subpackage_1, subpackage_2

As a result, the import operation continues to look for and execute ﹐ init ﹐ py in subpackage ﹐ 1 and subpackage ﹐ 2. (but import * will not be executed at this time.)

Under subpackage? 1, we add the? Init? Py file:

__all__ = ['test11', 'test12']
# Only test11 is imported by default
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 subpackage, 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

After understanding the working principle of "init". Py, you should be able to understand that this file is a normal python code file.

So you can put the initialization code in this file.

Posted by Cornelia on Thu, 24 Oct 2019 03:19:17 -0700