这篇“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 结构如下所示:
而 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 会去 sys.path 里面搜索。
比如我在 file2.py 的末尾添加一行代码:import sys; print(sys.path) 就可以打印 import 的搜索路径:
可以看出 sys.path 的顺序:
会先搜索执行脚本所在的路径
标准库
第三方库 site-packages
关于 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 提示我们:
ImportError: attempted relative import with no known parent package
也就是说相对导入不知道父包是谁,换句话说,这是一个子包,必须让父包来调用它,直接运行这个文件是不行的,即使你在 file4.py 的目录 subpackage1 同级的目录执行该文件也是不行的,见上图。
但是在 file4.py 的目录 subpackage1 同级的目录作为一个 module 来执行是可以的,如下图:
换句话说,我们把 subpackage1 作为一个包来让别人用,相对导入是可以的,比如说我们在目录 subpackage1 同级的目录新建一个 file5.py 的文件,内容如下:
file5.py:
from subpackage1 import file4。
然后,执行 python file5.py 可以看出,相对导入已经正常工作:
结论
如果是当做脚本文件直接运行的,使用绝对导入。
如果是当做模块供其他文件导入,使用相对导入。
4.一个自定义包的例子
先上一个图来看下目录及引用结构,方块的是目录,椭圆的是文件,曲线是引用:
其中 import_example 目录下有 setup.py 和 run.py
run.py 导入了 file4、file5、file6。
file4 导入了 file3,file5 导入了 file3。
file6 导入了 file2,file2 导入了 file1。
现在我们来执行一下 run.py 看下效果:
可以看出所有相对导入都已正常工作,虽然 file3 被导入了两次,但只执行了一次,说明 Python 内部已经考虑了同一个包的多重导入问题。自定义包就是让其他文件导入使用的,因此 pythonimportexample目录下都使用相对导入。
以上就是关于“Python中import是如何工作的”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注捷杰建站行业资讯频道。