一,什么是包
包是⼀种通过 '.模块名'来组织python模块名称空间的⽅式. 那什么样的东西是包呢? 我 们创建的每个文件夹都可以被称之为包. 但是我们要注意, 在python2中规定. 包内必须存在 __init__.py⽂文件. 创建包的目的不是为了了运⾏, ⽽是被导入使用. 包只是一种形式而已. 包的本 质就是一种模块。
为何要使用包? 包的本质就是一个文件夹, 那么文件夹唯一的功能就是将文件组织起来, 随着功能越写越多, 我们无法将所有功能都放在一个文件中, 于是我们使用模块去组织功能, 随着模块越来越多, 我们就需要用文件夹将模块文件组织起来, 以此来提高程序的结构性和可维护性。
我们可以说glance,api,cmd,db,kkkkk都是一个包。
policy.py
def fun(): print('policy')
坑1
111.py
from glance.api.policy import fun
fun() #得到结果policy
如果是这样写的就不行
import glance
glance.api.policy.fun() #报错
需要怎么改正呢,需要在在父包的__init__.py中导入子包
glance的__init__.py文件导入api,而且要从最根部导入
from glance import api
然后再在api的__init__.py文件中导入policy模块,也需要从最根部导入
from glance.api import policy
111.py
import glance
glance.api.policy.fun() #d得到结果policy
坑2,关于模块查找路径,通过sys.path来查看模块查找路径
glance和111.py在一个目录 glance目录下有api,cmd,db api目录下有policy,versions
如果在111.py中执行,那搜索路径从day21目录开始找,如果在policy.py中执行的,那查找路径就是api目录
policy.py
import versions #这样是没有问题,因为是从policy.py 中执行的,查找路径是api目录,而且versions就在api目录中
versions.fun1()
但是。。。。。。
111.py
from glance.api import policy #此时,在111.py中执行,查找路径就会day21目录,在引入policy模块时,执行到import versions就会报错,
报的错是找不到:ModuleNotFoundError: No module named 'versions'
相对导入和绝对导入
绝对导入
在111.py中执行,想要调用glance包中的内容,从最根部开始写,因为111.py的查找路径是day21目录,glance就在day21目录下,
于是乎就是要从glance开始写。如果是在policy.py中想调用versions.py,因为policy.py的查找路径是api目录,然而versions就在
api中,所以直接写import versions就行,这都是绝对导入
111.py
from glance.api import versions #这是绝对导入
policy.py
import versions #这也是绝对导入
相对导入 ..表示上一层,.表示本层
policy.py
from . import versions #表示在本层即api目录下引入versions
versions.fun1()
from ..cmd import manage #表示在上一层即glance目录下的cmd中引入manage
manage.fun2()
坑2:切记不能直接在policy.py中直接运行,即含有相对导入的py文件不能直接执行,会报错的,想要执行,只有在包外通过其他引入policy来执行
111.py
from glance.api import policy #通过这样就可以执行了
包的注意事项:
1,关于包相关的导入语句也分为import和from xxx import xxx两种,但无论使用哪种。无论在什么位置,在导入时必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则报错,可以带一连串的点
2,import导入文件时,产生名称空间中的名字来源于文件,import包,产生的名称空间中的名字同样来源于文件,即包下的__init__.py,导入包就是在导入该文件
3,包a和包b下有同名模块也不会冲突,如a.fun和b.fun来自两个名称空间