In python import study notes

  • 2020-05-24 05:44:14
  • OfStack

preface

There are two ways of organizing modules in python. One is simply an python file whose file name is the module name, and the other is a package, which is a directory containing several python files. There must be one file in the directory __init__.py , so the directory name is the module name, and the python file in the package can also be import by the package name and file name

import grammar

There are two types of import syntax

1. Direct import module


 import Module
 import Module as xx

2. import objects from modules (sub-modules, classes, functions, variables, etc.)


 from Module import Name
 from Module immport Name as yy

The as syntax is used to set aliases for objects (in this case, modules, classes, functions, etc.), and import introduces the object name into the namespace of the current file

Suppose you have the following directory structure


 ├ ─ ─  A.py
 └ ─ ─  pkg
  ├ ─ ─  B.py
  └ ─ ─  __init__.py

In the current directory, the following statements are valid


import A 
import pkg
import pkg.B
from pkg import B

To simplify the discussion, there will be no examples of the as syntax below

import steps

All module information loaded by python is stored in the sys.modules structure. When import1 modules are installed, the following steps are followed

If it's import A, check sys.modules Does A already exist in, if so, do not load, if not, create module object for A, and load A If it is from A import B, first create module object for A, then parse A, find B and populate A __dict__ In the

Nested import

In the import module, we may worry about whether a module will be import multiple times. If there are three modules A, B and C, A needs import B and C, B needs import C, then A will execute import C twice, import itself once, import B once. However, according to the import step mentioned above, On the second import, it was found that the module had been loaded, so import would not be repeated

But the following situation will report an error


#filename: A.py
from B import BB
class AA:pass

#filename: B.py
from A import AA
class BB:pass

In this case, either A.py or B.py will throw an ImportError exception, assuming that we are executing A.py, for the following reasons

.py executes from B import BB, scanning B.py and creating module objects for B in the A namespace, trying to find BB from B Scan B.py line 1 from A import AA , then it will scan A.py Scan A.py line 1 to execute from B import BB , since step 1 has already created module objects for B, it will be directly from module objects for B __dict__ Get BB from, then obviously BB is not available, so throw an exception

There are two ways to deal with this situation,

Change from B import BB to import B, or from A import AA to import A Swap the two lines of code in A.py or B.py

In summary, the important thing about import is to try to use import when you need it

The package import

When 1 directory has __init__.py When you file, the directory is a package of python

The import package and the import single file are the same. We can make an analogy like this:

When import is a single file, all the classes, functions and variables in the file can be used as objects of import import package when the package contains subpackages, files, and __init__.py Classes, functions, and variables in import can be used as objects

Suppose you have the following directory structure


pkg
 ├ ─ ─  __init__.py
 └ ─ ─  file.py

The contents of py are as follows


argument = 0
class A:pass

Execute the following statements in the same directory as pkg to OK


>>> import pkg
>>> import pkg.file
>>> from pkg import file
>>> from pkg import A
>>> from pkg import argument

But the following statement is wrong


>>> import pkg.A
>>> import pkg.argument

An error ImportError: No module named xxx Because when we execute import A.B , A and B must be modules (files or packages)

Relative and absolute imports

The format of the absolute import is import A.B or sys.modules1 , the relative import format is sys.modules2 or sys.modules3 ,. Represents the current module,.. On behalf of the upper module... Represents the upper module, and so on. When we have multiple packages, we may have requirements for content from one package import and one from another, which leads to absolute imports, which are often the most error-prone, again with concrete examples

The directory structure is as follows


app
 ├ ─ ─  __inti__.py
 ├ ─ ─  mod1
 │   ├ ─ ─  file1.py
 │   └ ─ ─  __init__.py
 ├ ─ ─  mod2
 │   ├ ─ ─  file2.py
 │   └ ─ ─  __init__.py
 └ ─ ─  start.py

Among them sys.modules4 Content is sys.modules5

sys.modules6 Content is sys.modules7

For ease of analysis, we have included in all py documents (including __init__.py ) add in line 1 sys.modules9

now sys.modules6 Relative import is used in app/mod1 __dict__1 Or under app __dict__2 Will be an error __dict__3

Execute under app __dict__4 or __dict__5 Will be an error __dict__6

More on that later, let's look at some of the rules for importing a module

In the absence of a clearly specified package structure, python is based on s 243en__ to determine the structure of one module in the package. If s 244en__, then s 248en is the top-level module with no package structure. If s 245en.B.C, then s 248en is the top-level module.

Basically follow this principle

If it is an absolute import, a module can only import its own submodules or modules of the same level as its top-level module and its submodules If it is a relative import, a module must have a package structure and can only import modules inside its top-level module

There is a directory structure as follows


 from Module import Name
 from Module immport Name as yy
0

A, B1, B2, C1, C2 are all packages, which are not listed here for the sake of simplicity __init__.py File, when file py package structure for A. B1. C1. file (note that is based on __dict__8 Instead of the disk's directory structure, execute in a different directory __dict__9 The corresponding package directory structure is not the same __dict__9 You can use the following absolute import


 from Module import Name
 from Module immport Name as yy
1

And relative imports as follows


 from Module import Name
 from Module immport Name as yy
2

What circumstance can let file. py package structure for A. B1. C1. file, has the following two

Execute in the upper directory of A from A import AA1 , at which point the package structure is explicitly specified Create file start.py in the upper directory of A from A import AA2 There are import A. B1. C1. file, then execute __dict__5 , at which point the package structure is based on __dict__9 the __dict__8 The variable to

Now let's look at the first two cases where things went wrong, the first execution __dict__1 and __dict__2 At this time, __dict__9 the __dict__8 for __main__ , that is to say, it is itself a top-level module and has no package structure, so it will report errors

The second case is in execution __dict__4 and __dict__5 When, the former explicitly tells the interpreter that mod1 is the top-level module, while the latter needs to import file1, and file1.py the __dict__8 for mod1.file1 , the top-level module is also mod1, so the file1.py Performed in the sys.modules7 An error is reported because mod2 is not inside the top-level module mod1. As you can see from the error stack, it's not from A import AA2 In absolute import times error, but in file1.py Relative import error

So how do you even execute it correctly? There are two ways. One is to execute it in the app upper directory __dict__0 , the other is to change the directory structure and put all the packages in one big package, as follows


app
 ├ ─ ─  pkg
 │   ├ ─ ─  __init__.py
 │   ├ ─ ─  mod1
 │   │   ├ ─ ─  __init__.py
 │   │   └ ─ ─  file1.py
 │   └ ─ ─  mod2
 │   ├ ─ ─  __init__.py
 │   └ ─ ─  file2.py
 └ ─ ─  start.py

from A import AA2 Content to __dict__2 , and then execute under app __dict__5

conclusion

The above is the whole content of this article, I hope the content of this article can help you to learn or use python, if you have any questions, you can leave a message to communicate.


Related articles: