一、模块的使用
1.什么是模块
模块就是一系列功能的集合体模块的表现形式为:
a.使用python编写的py文件
b.已被编译为共享库或DLL的C或C++扩展
c.把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件)
d.使用C编写并链接到python解释器的内置模块
模块分为三大类:
a.自定义模块
b.内置模块
c.第三方模块
2.为什么要用模块
a.可以下载别人的模块,然后直接使用。拿来主义。会极大的提高开发效率
b.将程序公用的功能组织到一个文件中,便于使用和管理
3.怎么用
一个py文件就是一个模块,若文件名为spam.py,则模块名为spam
import 导入
首次import导入模块会发生三件事:
a.创建一个模块spam.py的名称空间
b.执行模块对应的文件spam.py,将产生的名字丢到模块的名称空间中
c.在当前执行文件的名称空间中拿到一个名字spam,该名字就是指向模块spam.py的名称空间。
在当前执行文件中引用模块中的名字:模块名 如:spam.名字
ps:
a.重复导入无效
b.函数作用域关系在定义阶段就固定死了,与调用阶段无关
from .... import :为什么要这个? 简化import代码量
首次from...import导入模块会发生三件事:
a.创建一个模块spam.py的名称空间
b.执行模块对应的文件spam.py,将产生的名字丢到模块的名称空间中
c.将变量与spam名称空间的 变量地址绑定
注意:1.run.py的同变量名会在当前名称空间查找。
2.函数的作用域在定义阶段就固定死了
两种导入方式的对比:
相同点:
a.函数的作用域关系在定义阶段就固定死了,与调用位置无关
b.都创建对应的模块名称空间,都会执行一次py文件、初始化名称空间
不同点:
from...import:
优点:from...import 可以不用加前缀而直接引用名字,更简洁
缺点:容易与当前执行文件的名字冲突
import:
优点:指名道姓,肯定不会与当前执行文件的名字冲突
缺点:必须加前缀
as 关键字改名:
from ... import *:
* 会检索被导入模块中的__all__指定的名字,如果没指定,默认导入所有变量
二、循环导入的问题
模块循环/嵌套导入抛出异常的根本原因是由于在python中模块被导入一次之后,就不会重新导入,只会在第一次导入时执行模块内代码
在我们的项目中应该尽量避免出现循环/嵌套导入,如果出现多个模块都需要共享的数据,可以将共享的数据集中存放到某一个地方
在程序出现了循环/嵌套导入后的异常分析、解决方法如下
示例:
m1.py文件
m2.py文件
run.py执行
执行得到结果:
出现原因:先执行run.py--->执行import m1,开始导入m1并运行其内部代码--->打印内容"正在导入m1"
--->执行from m2 import y 开始导入m2并运行其内部代码--->打印内容“正在导入m2”--->执行from m1 import x,由于m1已经被导入过了,
所以不会重新导入,所以直接去m1中拿x,然而x此时并没有存在于m1中,所以报错
解决方法1:
导入语句放到最后,把所有名字的定义放到前面
解决方法2:导入语句放到函数中
三、区分python文件的两种用途
__name__:python内置变量。在满足某种条件自动触发使用。
1.可以直接执行运行
当做执行文件执行了:__name__ == '__main__'
2.可以被当做模块导入:
当做模块被导入时:__name__ == '模块名':
四、模块的搜索路径
1.优先从内存中查找:
a.导入模块spam
b.sleep 20秒
c.重新执行代码
2.其次查找内置模块
3.再次去 sys.path的环境变量里面依次查找
ps:导入模块一定要搞清楚执行文件是谁和被导入模块是谁。
sys.path第一个元素是以当前执行文件的路径为准
a.导入文件可以向sys.path append或inert路径
b.以执行文件路径为准,from...import模块