目录
包导入的搜索路径
包导入的搜索路径和python模块导入的搜索路径和顺序完全一样,具体可以参看笔者的这篇文章。但是要注意的是,这里的搜索路径指的是对最外层的那个包,例如from dir1.dir2 import mod语句,这里的搜索路径指的是对dir1的搜索路径,这时是和python模块导入的搜索路径和顺序完全一致的;而对于包内的文件或者包的导入,便直接通过点号进行搜索,在包导入语句中,点号就相当于是目录的层级结构的划分,比如上述语句中dir2表示在dir1目录下的一个目录,而mod.py则是dir2目录下的一个模块文件。
__init__文件的作用
在包导入中,对被导入的包,其目录下必须要有__init__.py文件,不然无法成功导入,不仅被导入包的目录下要求有该文件,如果对包内的其他目录进行导入,那么其他目录包内也必须有__init__.py文件,比如对于from dir1.dir2 import mod语句,不仅dir1下必须要有__init__.py文件,dir2目录下也必须要有__init__.py文件,这样才可以成功导入。
__init__.py文件内可以写任何python语句内容,并且在导入的时候会执行该文件;__init__.py文件的作用主要有两个:一是对包导入做一些可能必要的初始化行为,因为在导入包时会执行该文件;二是该文件会构建其所在目录名称的相应的命名空间对象,命名空间中的属性就是该文件中属性。假如现在在dir1下有目录dir2,文件mod1.py和__init__.py文件,那么如果__init__.py文件是一个空文件,这时import dir1后,由于__init__.py文件是空的,所以dir1对应的命名空间中没有属性,所以如果想通过dir1.mod1去获取mod1,会报错;但是此时如果__init__.py文件是如下内容,便会将mod1和dir2都初始化为dir1命名空间中的属性,这时便可以通过dir1.mod1和dir1.dir2进行合法访问。
from dir1 import mod1
from dir1 import dir2
包内相对导入
我们知道,对于模块的导入,是没有相对导入的,模块导入的搜索路径和顺序是严格按照sys.path中的路径和顺序进行的;但是对于包内模块文件中的导入语句,可以实现相对导入,具体的方法是通过点号实现,如from . import module, from .. import module,这里的单个点号表示从包内该模块文件所在的目录导入module,双点号表示从当前程序文件所在目录的上级目录导入module。