第六篇 模块基础
一 模块的四种形式
啥是模块
模块是一系列功能的集合体,而函数是某一功能的集合体,因此模块可以看成是一堆函数的集合体。一个py文件内部就可以放一堆函数,因此一个py文件就可以看成一个模块。如果这个py文件的文件名为module.py,模块名则是module。
模块的四种形式
2.1 自定义模块:如果你自己写一个Py文件,在文件内写入一堆函数,则它被称为自定义模块,即使用python编写的.py文件
2.2 第三方模块:已被编译为共享库或DLL的或C++扩展
2.3 内置模块:使用C编写并连接到python解释器的内置模块
2.4 包:把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包。
为啥使用模块
3.1 用第三方或者内置的模块是一种拿来主义,可以极大地提升开发效率
3.2 自定义模块,将我们自己程序中用到的公共功能,写入一个python文件,然后程序的各部分组件可以通过导入的方式来引用自定义模块的功能。
如何用模块
一般我们使用import和from...import导入模块
二 import和from...import
import模块名
import首次导入模块发生了3件事:
1.1以模块为准创造一个模块的名称空间
1.2执行模块对应的文件,将执行过程中的名字都丢到模块的名称空间
1.3在当前执行文件中拿到一个模块名
模块的重复导入会直接引用之前创造好的结果,不会重复执行模块的文件,即重复导入会发生:spam=spam=模块名称空间的内存地址、
from模块名import具体的功能
from...import...首次导入模块发生了3件事:
2.1 以模块为准创造一个模块的名称空间
2.2执行模块对应的文件,将执行过程中产生的名字都丢到模块的名称空间
2.3 在当前执行文件的名称空间中拿到一个名字,改名字直接指向模块中的某一个名字,意味着可以不用加任何前缀而直接使用。
优点:不用加前缀,代码更加精简
缺点:容易与当前执行文件中名称空间中的名字冲突
import和from.....import的异同
相同点:
- 两者都会执行模块对应的文件,两者都会产生模块的名称空间
- 两者调用功能时,需要跑到定义时寻找作用域关系,与调用位置无关
不同点:
import需要加前缀,from import不用加前缀。
三 循环导入问题
模块m1和m2相互导入,此时可能会出现一种情况:
m1从m2导入的名称是在m2中的导入m1语句下面定义的
m2从m1导入的名称是在m1中的导入m2语句下面定义的
因而m1和m2中的导入语句都找不到目标名称,就像陷入了循环一样,都不会执行下面的代码
==解决方法==
- 在import语句之前定义目标函数
- 在函数体导入,因为函数只检测语法,不执行代码
四 模块的搜索路径
模块搜索路径顺序
- 先从内存中已经导入的模块中寻找
- 内置的模块
- 环境变量sys.path中找
强调:sys.path的第一个值是当前执行文件的所在文件夹
五 python文件的两种用途
执行文件
脚本:一个文件就是整个程序,用来被执行
当作模块导入
模块:文件中存放着一堆功能,用来被导入使用
六 包
啥是包
包是模块的一种形式,包的本质就是一个含有.py的文件或文件夹。
为啥使用包
为了方便模块设计者对模块的管理,维护方便。因此我们可以使用包来扩展模块的功能
使用方法
==导入模块发生的三件事==
- 创建一个包的名称空间
- 执行py文件,将执行过程中产生的名字存放于名称空间中。
- 在当前执行文件中拿到一个名字aaa,aaa是指向包的名称空间
==导入包发生的三件事==
- 创建一个包的名称空间
- 由于包是一个文件夹,无法执行包,因此执行包下的.py文件,将执行过程中的名字存放于名称空间中(即包名称中存放的名字都是来自于.py)
- 在当前执行文件中拿到一个名字aaa,aaa是指向包的名称空间的
==导入包就是在导入包下是.py,并且可以使用以下两种方式导入==
- import
- from import
==绝对导入和相对导入==
绝对导入:
# aaa/.py
from aaa.m1 import func1
from aaa.m2 import func2
相对导入:
- .代表当前被导入我呢见加所在的文件夹
- ..代表当前被导入文件治所在的文件夹的上一级
- ...代表当前被导入文件所在的文件夹的上一级的上一级
注意事项
- 包内所有的我呢见都是被导入使用的,而不是被直接运行的
- 包内部模块之间的导入可以使用绝对导入(以包的根目录为基准)与相对导入(以当前被导入的模块所在的目录为基准),推荐使用相对导入
- 当文件是执行文件时,无法在该文件内用相对导入的语法,只有在文件时被当作模块导入时,该文件内才能使用相对导入的语法
- 凡是在导入时带点的,点的左边都必须是一个包。