概念:除了模块名之外,导入也可以指定目录路径。Python代码的目录就称为包,因此这类导入就称为包导入。事实上,包导入是把计算机上的目录变成另一个Python命名空间,而属性则对应于目录中所包含的子目录和模块文件。
包导入基础
语句格式:
# import语句
import dir1.dir2.mod
# from语句
from dir1.dir2.mod import x
上面的语句代表了这样的目录结构:dir0\dir1\dir2\mod.py
容器目录dir0需要添加在模块搜索路径中(除非这是顶层文件的主目录),相对于我们之前介绍的sys.path模块搜索路径列表中的一个目录。
包和搜索路径设置
模块搜索路径上的目录提供了平台特定的目录路径前缀,之后再在import的那些路径左边添加了这些路径,import语句以与平台不相关的方式,提供了目录路径写法。
__init__.py包文件
如果选择使用包导入,就必须多遵循一条约束:包导入语句的路径中每个目录内都必须有__init__.py这个文件,否则导入包会失败。比如上面的例子,在dir1和dir2内都必须包含__init__.py这个文件。
所以针对上述包导入语句必须遵循下列规则:
dir1和dir2中必须都包含有一个__init__.py文件
dir0是容器,不需要__init__.py文件;如果有的话,这个文件也会被忽略
dir0(而非dir0\dir1)必须列在模块搜索路径上(也就是此目录必须是主目录,或者列在PYTHONPATH之中)
__init__.py文件扮演了包初始化的钩子、替目录产生模块命名空间以及使用目录导入时实现from *(也就是from ... import *)行为的角色。
包的初始化:
Python首次导入某个目录时,会自动执行该目录下__init__.py文件中的所有程序代码。
模块命名空间的初始化:
在包导入的模型中,脚本内的目录路径,在导入后会变成真实的嵌套对象路径。
from*语句的行为
作为一个高级功能,可以在__init__.py文件内使用__all__列表来定义目录以from*语句形式导入时,需要导出什么。
包导入实例
如果一个代码的安装层次如下所示:
现在,就是把共同根目录添加到搜索路径中。如果程序的导入就相对于这个通用的根目录,就能以包导入,导入任何一个系统的工具文件:该文件所在目录名称会使其路径具有唯一性。
注意:如果需要读取两个或两个以上路径内的同名属性时,才需要使用import,在这种情况下不能使用from。如果被调用的函数名称在每个路径内都不同,from语句就可以避免每当调用其中一个函数时,就得重复完整的包的路径的问题。
包相对导入
参考文章:http://kuanghy.github.io/2016/07/21/python-import-relative-and-absolute
Python3.0中的变化
它修改了模块导入搜索路径语义,以默认地跳过包自己的目录。导入只是检查搜索路径的其他组件。这叫做“绝对”导入
它扩展了from语句的语法。以允许显式地要求导入只搜索包的目录。这叫做“相对”导入语法
这一变化的影响是,在Python3.0中,我们通常必须使用特殊的from语法来导入与导入者位于同一包中的模块,除非你从一个包根目录拼出一个完整的路径。没有这一语法,你的包不会自动搜索到。
相对导入基础知识
Python 相对导入与绝对导入,这两个概念是相对于包内导入而言的。包内导入即是包内的模块导入包内部的模块。
绝对导入的格式为 import A.B
或 from A import B。
相对导入格式为 from . import B
或 from ..A import B
,.
代表当前模块,..
代表上层模块,...
代表上上层模块,依次类推。