今天学习了包的基础知识:
一、什么是包:
包是一种模块 但本质上就是一个文件夹
与普通文件夹的区别就是其中包含一个init文件
二、包的作用
包的作用就是从文件夹级别组织代码
目的就是为了提高维护性
三、什么时候应该使用包
之前我们将代码抽取到模块中 从文件级别组织代码 但是如果模块比较多的情况下 结构依然混乱
此时我们就需要使用包来组织代码
四、包的使用
创建一个包
右键 new-> python packge
使用包
既然包 也是模块 那么使用方式就是一样的 使用import来导入包
import 包名
五、init文件的使用
我们说包也是一种模块 所以内部原理是一样的
1、创建名称空间
2、执行模块中的代码
3、在执行文件中产生名称指向模块名称空间
但是现在包他是一个文件不是一个py文件那么第二步该怎么执行呢?
这时候init.py就派上用场了
在导入包时 实际上执行的就是这个init文件
好处:
如此一来我们可以使用init来把一个文件夹变成一个模块 这个模块的种类是包
通常情况下 一个包中有多个模块 并且这些模块经常会同时被导入使用
这时候你可以在init中将需要的模块一次性导入 当外界在使用这个包的时候 就无需再挨个导入了
总结:
init的作用是初始化包 初始化其实就是将包中需要提供给外界的模块统一导入 打包在一起
用户导入了包 就能使用所有的功能
注意:
init 导入模块文件时 由于是作为模块导入 所以sys.path中并不包含 模块所在目录 所以应该导入时要指定包名
pack包下的init
from pack import module
import pack.module
另外:
init文件 在Python2中是必须的Python3中可选的 但是建议都要有规范
六、包的嵌套
定义:包中有包如下
要使用子包中的内容 方法一致 在子包中的init中导入需要的内容 但是注意 不管是不是子包 都是作为模块导入
所以sys.path中肯定不包含子包路径 导入时需要从执行文件目录往下找
subpack包下的 init文件
import pack.subpack.module4
七、导入包时的注意事项
使用import导入模块时 可以加点来访问下一层
import pack.subpack.module4
==注意 点的左边必须是包名==
我们也可以使用from来导入
from pack.subpack import module4
==注意 import后面的内容不可以包含点 必须是一个明确的名字==
八、相对导入与绝对导入
利用上面的例子 我们继续来思考
很多时候一个包内的模块需要相互调用对方的功能来完成操作
按照我们之前的导入方式 从执行文件开始一层一层往下找是可以的
但是一个问题是如果报的层级较多 你的导入语句会很长
另一个问题 如果我们后期需要修改包的名称 那你需要将每一个导入语句都进行修改
来看一下例子:
我们可以使用相对导入的方式来简化书写并提高我们的代码的扩展性
注意:
==相对导入仅能用于模块之间互相导入 不能用于执行文件中==
常见错误演示
1、绝对导入时没有从执行文件目录开始
2、在执行文件中使用相对导入
3、跳出顶层包
ValueError:attempted relative import beyond top-level package