一、什么是模块
模块就是一系列功能的集合体。在Python中,一个py文件就是一个模块,比如module.py就是一个模块,其中模块名是module。
模块的四种存在方式(通用类别):
- 使用python编写的.py文件(任何一个py文件都可以作为模块)
- 把一系列功能属性相近的模块组织到一起的文件夹(包)
- 使用C编写并链接到python解释器的内置模块
- 已被编译为共享库或DLL的C或C++扩展
二、为何使用模块?
- 从文件级别组织代码,是同特性的功能能统一管理
- 可以使用系统或第三方模块(拿来主义),来提高开发效率
三、使用模块
(一)import 导入模块
import 模块名
1.首次导入模块发生的三件事
①创建一个模块的名称空间
②执行模块对应文件,将产生的名字存放于①中的名称空间。
③在当前执行文件中,拿到一个模块名,该模块指向①的名称空间
强调:
每一个文件都会产生自己的全局名称空间,且相互不影响,模块中功能的执行始终以模块自己的命名空间为准。
多次导入,只会编译执行模块一次,将其加载到内存,之后的都是直接对名字的引用。
模块名.模块内定义的名字——引用功能
2.起别名
通过as关键字可以给模块起别名: 模块名一旦起别名,原模块名就不能再使用
3.优点
1.将复杂冗长的模块名简明化
import my_name_is_long as mg
print(mg.num)
2.可以统一功能
engine = input('数据库选择 1:mysql 2:oracle:')
if cmd == '1':
import mysql as db
else:
import oracle as db
db.功能() # 不需动这块
4.一行导入多个模块(不推荐使用)
import 模块名1,模块名2,……,模块名n
推荐写成多行。
(二)from导入模块
from 模块名 import 对象
可以指名道姓导入模板中所有想导入的名字
1.首次导入模块的三件事
①创建一个模块的名称空间
②执行模块对应文件,将产生的名字存放于①中的名称空间。
③在①名称空间中直接拿到模块中的名字,可以直接使用,不加任何前缀。
强调
执行模块中的功能,始终以模块的名称空间为准。
from……import 名字,拿到的名字可以不加前缀直接使用,使用方便,但问题是容易与当前执行文件相同的名字冲突。
2.起别名
from 模块名 import 原名 as 新名
3.在一行中导入多个
from 模块名 import 名,名,……,名
4.from 模块名 import *
导入模块中的所有名字,默认不会导入_开头的名字
配合__all__ = ['名字1','名字2',……'名字n']
,此时 * 只会导入列表中的名字(包括_开头的名字)
不建议直接导入 * ,因为可读性差,且极容易出现变量重名
四、区分Python文件的两种用途
print( __name__)
name__的值
①在文件被直接执行的情况下,等于__main
②在文件被导入的情况下,等于模块名。
if __name__ == '__main__'
测试代码块
五、模块的搜索路径
内存中已经加载的模块—》内置模块—》sys.path路径中包含的模块。 sys.path的第一个值是当前执行文件所在的文件夹。
import sys
sys.path.append(r'路径') # 在最后添加
sys.path.insert(index,r'路径') # 指定位置插入
六、模块导入的执行流程
导入模块的指令:
1.相对于 函数名() 调用函数体,函数调用会进入函数体,从上至下逐句解释执行函数体代码
2.导入模块,会进入模块文件,从上至下逐句解释执行模块文件代码
3.如果在模块中又遇到导入其他模块,会接着进入导入的模块,从上至下逐句解释执行文件中代码,依次类推
这会导致下面循环导入这个问题
循环导入
模块之间出现了环状导入,如:m1.py 中导入了m2,m2.py 中又导入了m1
导入模块是要使用模块中的变量 ,正常逻辑都是在文件最上方先完成对模块的导入,再在下方定义自身模块变量,以及使用导入的模块中的变量 ,由于导入模块的特殊机制,第一次导入模块会编译执行导入的模块,也就是会进入模块逐句执行模块内容,再次导入只是使用内存中的名字,就会出现下面的情况,m2在使用m1中的变量x,但变量x却并未产生,这就出现了循环导入问题。
m1.py文件
import m2
x = 10
print(m2.y)
m2.py文件
import m1
y = 10
print(m2.x)
解决方法:延后导入
1、将循环导入对应包要使用的变量提前定义,再导入响应的包
2、将导包的路径放到函数体中,保证存放导包逻辑的函数调用在要使用的变量定义之后
重点:
问题:from导包极容易出现循环导入问题
解决:建议from导入方式改用import导入方式