包的作用:
包 是一种通过使用 ’模块名‘ 来组织python模块名称空间的方式
包的本质就是一个文件夹,那么文件夹唯一的功能就是将文件组织起来
与普通文件夹的区别就是其中包含一个__init__文件
包的作用:
包的作用就是从文件夹级别组织代码
目的就是为了提高维护性
什么时候应该使用包?
之前我们将代码抽取到模块中 从文件级别组织代码 但是如果模块比较多的情况下 结构依然混乱 此时我们需要使用包来组织代码
包的使用
创建一个包
右键new => python package
使用包
既然包也是一种模块 那么使用方式就是一样的 使用import来导入包
import 包名
init文件的作用
思考在导入包时发生了什么?
包也是一种模块 所以内部原理是一样的
1.创建名称空间
2.执行模块中的代码
3.在执行文件中产生名称指向模块名称空间
包是一个文件夹 而不是一个py文件
这个时候init.py就派上用场
好处:
使用init来吧把一个文件夹变成一个模块 这个模块的种类是包
通常情况下 一个包中有多个模块 并且这些模块经常会同时被导入使用
这时候可以在init中将需要的模块一次性导入 当外界在使用这个包的时候 就不需要再挨个导入了
总结:
init的作用就是初始化包 其实就是将包中需要提供给外界的模块统一导入 打包再一起
用户导入了包 就能使用所有的功能
注意:
init 导入模块文件时 由于是作为模块导入 所以sys.path中包含 模块所在目录 所以应该导入时要指定包名
pack包下的init
from pack import module
import pack.module
另外
init文件 再python2中是必须的 而再python3中是可选的,但是建议都要有 规范
包的嵌套
定义: 包中有包
要使用子包中的内容 方法一致 再子包中的init中导入需要的内容 但是注意 不管是不是子包 都是作为模块导入
所以sys.path中可定不包含子包路径 导入时需要从执行文件目录往下找
suback包下的 init文件
import pack.subpack.module4
导入包时的注意事项
使用import导入模块时 可以用加点来访问下一层
import pack.subpack.module4
注意: 点的左边必须时包名
我们也可以使用from来导入
from pack.subpack.module4
注意:import后面的内容不可以包含点,必须是一个明确的名字
相对导入与绝对导入
一个包内的模块需要互相调用对方的功能来完成操作
按照之前的导入方式, 从执行文件开始一层一层往下找是可以的
但是如果包的层级较多,你的导入语句会很长
另一个问题 如果我们后期需要修改包的名称 那需要将需要将每一个导入语句都进行修改
我们的最顶级包glance是写给别人用的,然后再glance包内部也会有彼此之间相互导入的需求,这时候就有绝对导入和相对导入两种方式:
绝对导入:以glance作为起始
相对导入:用。或...的方式最为起始(只能再一个包中使用,不能用于不同目录内)
例如:我们在glance/api/version.py中想要导入glancce/cmd/manage.py
在glance/api/version.py
#绝对导入
from glancce.cmd import manage
manage.main()
相对导入
from . . cmd import manage
manage.main()
绝对导入和相对导入的总结:
绝对导入:
以执行文件的sys.path为起点开始导入,称之为绝对导入
优点:执行文件与被导入的模块中都可以使用
缺点:所有导入都是以sys.path为起始点,导入麻烦
相对导入:
参照当前所在文件为起始点开始查找,称之为相对导入
符号: . 代表当前苏所在文件的文件夹 . . 代表上一级文件夹 . . .代表上上级的文件夹
优点导:导入更加简单
缺点:之只能在导入包中的模块时才能使用
#注意:
1.相对导入只能用于包内部模块之间的相互导入,导入者与被导入者都必须在一个包内
2.attempted relative import beyond top_level package 试图早顶级包之外使用相对导入时错误的,言外之意,必须在顶级包内使用相对导入,没增加一个,代表跳到上一级文件夹,而上一级不应该超出顶级包
所包含的模块都是用来被导入的,而不是被直接执行的,而环境变量都是以执行文件为准的