模块
1、什么是模块
常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀。
但其实import加载的模块分为四个通用类别:
1 自定义模块:使用python编写的代码(.py文件)
2 第三方模块:已被编译为共享库或DLL的C或C++扩展
3 包:包好一组模块的包
4 python内置模块:使用C编写并链接到python解释器的内置模块
2、为什么使用模块
1、将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行
2、为了方便管理,我们通常将程序分成一个个的文件,除了当作脚本运行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用
3、如何使用模块
3.1 注意点
-
为了防止对同一模块的重复导入,python的优化手段是:
第一次导入后就将模块名加载到内存,以
my_module为例后续的
import语句仅是对已经加载到内存中的模块对象增加了一次引用,不会重新执行模块内的语句
sys.modules中可以找到当前已经加载的模块 -
每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个模块的名称空间当做全局名称空间
3.2 首次导入模块时发生的事情
- 为模块文件
my_moudle.py创建新的名称空间 - 在新创建的命名空间中执行模块中包含的代码
- 用模块文件名
my_moudle创建名字来引用该命名空间
3.3 import 模块名
3.3.1
添加了模块名称空间的引用,等同于将模块源文件的名称空间带到当前文件名称空间中,使用时必须是模块名.名字的方式
3.3.2
为模块名起别名,相当于m1=1;m2=m1
import my_module as sm
print(sm.money)
3.3.3
在一行导入多个模块
import sys,os,re
3.4 from ... import ...
3.4.1
-
from语句相当于import,也会创建新的名称空间,但是将my_module中的名字直接导入到当前的名称空间中,在当前名称空间中,直接使用名字就可以了from my_module import read1,read2 -
如果当前有重名
read1或者read2,那么会有覆盖效果接使用read1和read2就好了,执行时,仍然以my_module.py文件全局名称空间
3.4.2
也支持as
from my_module import read1 as read
3.4.3
也支持导入多行
from my_module import read1,read2,money
3.4.4 from my_module import *
-
from my_module import *把my_module中所有的不是以下划线(_)开头的名字都导入到当前位置因为
*你不知道你导入什么名字,很有可能会覆盖掉你之前已经定义的名字可读性极其的差,在交互式环境中导入时没有问题
-
在
my_module.py中新增一行,限制from my_module import *能导入的名称__all__=['money','read1'] #这样在另外一个文件中用from my_module import *就只能能导入列表中规定的两个名字
3.4.5 循环导入
模块mi和m2相互导入
此时可能会出现一种情况:
m1从m2导入的名称是在m2中的导入mi语句下面定义的
m2从m1导入的名称是在m1中的导入m2语句下面定义的
因而m1和m2中的导入语句都找不到目标名称,就像是陷入了循环一样,都不会执行下面的代码
解决办法:
1、在import语句之前定义目标名称
2、在函数体内导入,因为函数只检测语法,不执行代码
3.4.6模块的加载与修改
- 每个模块只被导入一次,放入字典
sys.modules中,如果你改变了模块的内容,你必须重启程序,python不支持重新加载或卸载之前导入的模块 - 删了
sys.modules中的模块对象仍然可能被其他程序的组件所引用,因而不会被清除
3.5 把模块当作脚本运行
通过模块的全局变量__name__来查看模块名:
- 当做脚本运行:
__name__等于'__main__' - 当做模块导入:
__name__= 模块名
作用:用来控制.py文件在不同的应用场景下执行不同的逻辑
if __name__ == '__main__':
3.6 模块搜索路径
内存中已经加载的模块->内置模块->sys.path路径中包含的模块
-
python解释器在启动时会自动加载一些模块,可以使用
sys.modules查看 -
在初始化后,python程序可以修改
sys.path,路径放到前面的优先于标准库被加载import sys sys.path.append('/a/b/c/d') sys.path.insert(0,'/x/y/z') #排在前的目录,优先被搜索
3.7 编译python文件
为了提高加载模块的速度,python解释器会在__pycache__目录中下缓存每个模块编译后的版本
python解释器在以下两种情况下不检测缓存:
-
在命令行中被直接导入模块,每次导入都会重新编译,并且不会存储编译后的结果
python -m my_module.py -
源文件不存在,那么缓存的结果也不会被使用,如果想在没有源文件的情况下来使用编译后的结果,则编译后的结果必须在源目录下
3.8 dir()函数
内建函数dir()是用来查找模块中定义的名字,返回一个有序字符串列表
import my_module
dir(my_module)

浙公网安备 33010602011771号