Home>Article>Backend Development> Learn the Python module import mechanism and the specifications of large projects

Learn the Python module import mechanism and the specifications of large projects

coldplay.xixi
coldplay.xixi forward
2020-09-27 17:38:16 2707browse

Python Video Tutorialcolumn today introduces you to learn the Python module import mechanism and the specifications of large projects.

Learn the Python module import mechanism and the specifications of large projects

Preface

In the process of using Python in our daily projects, we often need to solve the import problems of each module, and we often encounter reference path searches. There are problems such as cross-importing modules and so on, so I wrote this article to describe Python’s module import mechanism and the module import specifications we should follow in our daily large-scale projects

Python module import

In daily programming, in order to reuse the code logic we have written, we will encapsulate these codes into modules. When needed, we can directly import and reuse them to improve our development efficiency. Modules can define functions, classes, variables, and can also contain executable code. There are three types of module sources: ①Python built-in modules (standard library); ②Third-party modules; ③ Custom modules;

Import principle

The import of modules is generally done by using theimportkeyword in the file header. Importing a module is equivalent to executing it once and then importing it. module, and then establishes a connection with the namespace of the imported module in this namespace, which is equivalent to creating a new variable in this namespace. The name of this variable is the name of the imported module and points to the namespace of the imported module. Therefore, the imported module is equivalent to a variable.Therefore, importing the same module multiple times will only be executed the first time it is imported.(Subsequent imports will determine that the module variable already exists and will not be executed)

Learn the Python module import mechanism and the specifications of large projects

Path search mechanism

Every imported module will be in the Python built-in dictionarysys.modules. Once Python is started, it will be Loaded in memory, when we import new modules, sys.modules will automatically record the module. Python's module search path mechanism is:

  1. Check whether the module exists in all paths insys.path, and if so, open up a new space to load the module;
  2. Check whether there are built-in packages or installed third-party packages in sys.modules, and if so, open up a new space to load the module;

So for the modules we write ourselves, if we encapsulate and publish When it comes to PyPi, you can install it directly with pip install and load it into the memory at startup. You can view it through sys.modules For modules that only need to be reused in this project, we add their paths tosys.pathin the reused code, and the module can also be referenced.

Absolute path import

All module imports start from the "root node". The location of the root node is determined by the path in sys.path. The root directory of the project is usually automatically in sys.path. If you want the program to be executed everywhere, you need to manually modify sys.path

import sys,os BASE_DIR = os.path.dirname(os.path.abspath(__file__))#项目根目录所在的绝对路径sys.path.append(BASE_DIR)import A, B #导入A、B包复制代码

Relative path import

Just care about the module location relative to your current directory. It cannot be executed directly inside the package (an error will be reported). No matter where the root node is, the relative position of the modules within the package is correct.

#from . import b2 #这种导入方式会报错,只有在包内部直接执行的时候才可以这样导入。import b2#正确b2.print_b2()复制代码

Python module import FAQ

  • When importing a package name individually, all submodules contained in the package will not be imported. Solution: The imported package also contains imports of other packages. At this time, you need to import all modules under the package in theinit.py file of each package, so that the top layer can directly reference the bottom layer. The classes and methods of the package

initFile

When there isinit.py in a folder, it means this file A folder is a package (package), and multiple modules (modules) under it form a whole, and these modules (modules) can be imported into other codes through the same package (package). Theinit.py file is used to organize packages, facilitate management of references between modules, and control the import behavior of packages.

This file can contain no content, that is, it is an empty file (when it is empty, nothing can be done by just using the import [package] form). It just needs to exist, which is equivalent to a mark.

In python3, even if there is noinit.py file under the package, the import package will still not report an error, while in python2, the file must be under the package, otherwise import The package will report an error

allVariable

allis an important variable used to specify that this package (package) is imported * When, which modules will be imported into [the current scope]. Modules not in thealllist will not be referenced by other programs. You can rewriteall, such asall= ['name of module 1 of the current package to which it belongs', 'name of module 1']. If this is written, the module name in the list will be used. Import

name变量

在包内部直接运行时,包的name== 'main',但是在外部导入包是,可以通过

if __name__ == '__main__':复制代码

来避免实现包内部调试时的逻辑

循环导入

当两个模块A和B之间相互import时,就会出现循环导入的问题,此时程序运行会报错:can not import name xxx,如:

# a.pyprint('from a.py')from b import x y = 'a'复制代码
# b.pyprint('from b.py')from a import y x = 'b'复制代码

我们来分析一下这种错误是怎么出现的:

  1. 在sys.modules中查找 符号“module b”;
  2. 如果符号“module b”存在,则获得符号“module b”对应的module对象; 从的dict中获得 符号“x”对应的对象。如果“x”不存在,则抛出异常“ImportError: cannot import name ‘x’”
  3. 如果符号“module b”不存在,则创建一个新的 module对象。不过此时该新module对象的dict为空。然后执行module b.py文件中的语句,填充的dict

因此在a.py中执行from b import x的顺序就是1->3,先引入b,b里面from a import y由相当于执行了a.py,顺序是1->2,因为此时b已经引入所以不会执行3,2中无法找到x对象,因为引入b时还没执行到x='b'这一步,所以报错了

解决办法

  1. 延迟导入,把import语句写在方法/函数里,将它的作用域限制在局部;
  2. 顶层先引入模块,再把from x import y改成import x.y形式;
  3. 其实出现循环引用问题的根本原因是程序设计不合理,每个包都应该由上层使用的模块去导入,而不应该在包与包之间各种相互导入,所以应该更改代码布局,可合并或分离竞争资源;

大型项目中Python模块导入规范

分离模块,将同一类别的模块放在同一目录下,形成类别分明的目录架构,如:

Learn the Python module import mechanism and the specifications of large projects

  1. 每一个模块目录都要写init.py文件,可以同时定义all限定可导入的范围;
  2. 源码根目录可以定义BASE_DIR,限定好根目录路径,启动py文件可以用绝对路径导入各个模块,将必要模块都加入到sys.path中;
  3. 各个服务之间(例如model需要引入common的模块方法),可以通过相对路径引用模块;
  4. 程序设计时避免循环导入,可由调用者(服务文件)作为上层第三方引入需要的各个模块,这样就可以减少各个模块的相互导入。

更多相关免费学习推荐:python视频教程

The above is the detailed content of Learn the Python module import mechanism and the specifications of large projects. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.im. If there is any infringement, please contact admin@php.cn delete