Python中import是如何工作的

开发技术 作者:zzz 2024-05-10 19:40:01
这篇“Python中import是如何工作的”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价�...

这篇“Python中import是如何工作的”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python中import是如何工作的”文章吧。

1.什么是模块(module),什么是包(package)

模块(module)

模块与包的关系,可以类比文件和目录,模块就是文件。

Python 文档中这样描述,一个 Python 文件就是一个模块,Python 的文件名(不带后缀.py)就是模块名。

一个 module 可以包含变量、函数和类,它们是该 module 定义的命名空间的一部分,因此变量的命名问题不是问题,因为两个不同的模块可以有同名的变量、函数和类。

包(package)

模块与包的关系,可以类比文件和目录,包就是目录。

package 里面可以有 module,也可以有子包(sub-package)。一个模块定义一个命名空间,以便变量、函数和类可以在两个不同的模块中具有相同的名称,同样的,一个包对其组成的包和模块做同样的事情,可以通过点号访问主包中的模块和包。

一个基本的 package 可以包含 sub-package、modules、__init__.py(Python 3.3 之后非必需)、setup.py。一个可能的 package 结构如下所示:

Python中import是如何工作的

而 setup.py 存在于你的 package 所在的主目录中,包含配置信息,如所需的依赖项、脚本和子包。你还可以指定有关 package 的元数据,例如 package 的名称、作者、描述等。

setup.py 是 pip 用来安装你的包的文件。

2.import 时发生了什么

先举一个简单的例子,比如说同一个目录有两个文件,file1.py 和 file2.py,内容很简单,就打印各自的文件名,不同的是 file2.py 里面 import 了 file1:

#file1.py
print("This is file1.py")
#file2.py
print("This is file2.py")
import file1

运行 file2.py 可以得到下面的结果:

 python file2.py
This is file2.py
This is file1.py

可以看出:

  • import 很直观,用谁就 import 谁。

  • import 语句就是一个普通的语句,可以放在任何位置。

  • 一个文件被 import 的时候,就会被执行,其内部的类或对象将添加到其命名空间。

我们还要知道 import 的搜索顺序,只需要记住一点,那就是 import 会去 sys.path 里面搜索。

比如我在 file2.py 的末尾添加一行代码:import sys; print(sys.path) 就可以打印 import 的搜索路径:

Python中import是如何工作的

可以看出 sys.path 的顺序:

  • 会先搜索执行脚本所在的路径

  • 标准库

  • 第三方库 site-packages

关于 sys.path 需要你注意的是:

  • 在解释器环境下,sys.path[0] 就是解释器启动时所在的路径 ''

  • sys.path 并不会依赖当前程序的工作路径 - os.getcwd(),仅仅依赖第一个脚本所在的路径:

Python中import是如何工作的

  • 如果一个模块导入另一个模块,而后者又导入另一个模块,则第一个模块的 sys.path 是解释器搜索第二个导入语句的位置。

一旦模块或包被找到,就会执行该模块或包。如果包里面有初始化文件 __init__.py,导入的时候,会先执行 __init__.py。

然后要导入的项目就添加到了其命名空间内,我们可以通过 xx.yy 的方式来使用。

3.什么时候用相对导入,什么时候用绝对导入

先看看什么是绝对导入,所谓绝对导入就是这样的形式:

import aa
import aa.bb
from aa import bb

这样的方式很直观, import 会去 sys.path 查找就行了,如果遇到了 ModuleNotFoundError,思考一下为什么 sys.path 没有我们要导入的包,或者手动把这个包的路径插入到 sys.path 中去。

再看看什么是相对导入,所谓相对导入就是这样的形式:

from . import aa
from .aa import bb
from .. import yy

也就是说相对路径中有个 . 号,用来表明要导入的模块或当前的包的相对位置。

举个例子,我们 pythonimportexample 目录下新建一个目录 subpackage1,在 subpackage1 内新建两个文件 file3.py、file4.py。

内容如下:

file3.py :

print("This is file3.py")

file4.py:

from . import file3
print("This is file4.py")

只要我们直接运行 file4.py,那是一定会报错的:Python中import是如何工作的

Python 提示我们:

ImportError: attempted relative import with no known parent package

也就是说相对导入不知道父包是谁,换句话说,这是一个子包,必须让父包来调用它,直接运行这个文件是不行的,即使你在 file4.py 的目录 subpackage1 同级的目录执行该文件也是不行的,见上图。

但是在 file4.py 的目录 subpackage1 同级的目录作为一个 module 来执行是可以的,如下图:

Python中import是如何工作的

换句话说,我们把 subpackage1 作为一个包来让别人用,相对导入是可以的,比如说我们在目录 subpackage1 同级的目录新建一个 file5.py 的文件,内容如下:

file5.py:

from subpackage1 import file4。

然后,执行 python file5.py 可以看出,相对导入已经正常工作:

Python中import是如何工作的

结论

  • 如果是当做脚本文件直接运行的,使用绝对导入。

  • 如果是当做模块供其他文件导入,使用相对导入。

4.一个自定义包的例子

先上一个图来看下目录及引用结构,方块的是目录,椭圆的是文件,曲线是引用:

Python中import是如何工作的

其中 import_example 目录下有 setup.py 和 run.py

run.py 导入了 file4、file5、file6。

file4 导入了 file3,file5 导入了 file3。

file6 导入了 file2,file2 导入了 file1。

现在我们来执行一下 run.py 看下效果:

Python中import是如何工作的

可以看出所有相对导入都已正常工作,虽然 file3 被导入了两次,但只执行了一次,说明 Python 内部已经考虑了同一个包的多重导入问题。自定义包就是让其他文件导入使用的,因此 pythonimportexample目录下都使用相对导入。

以上就是关于“Python中import是如何工作的”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注捷杰建站行业资讯频道。

原创声明
本站部分文章基于互联网的整理,我们会把真正“有用/优质”的文章整理提供给各位开发者。本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
本文链接:http://www.jiecseo.com/news/show_26343.html
python import