1.模块介绍
所谓的模块就是一系列可以实现特定功能的代码块,组成的一个py文件,这个文件就可以称为一个模块,相当于我们之前在一个py中定义了很多我们写程序的函数,这些一个个的函数其实就是模块里面的一个个的功能块,它可以在自身所在的py文件中运行,也可以被作为一个模块,在别的程序导入且被执行
2.为什么要用模块
1、从文件级别组织程序,更方便管理
随着程序的发展,功能越来越多,为了方便管理,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理。这时我们不仅仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用 2、拿来主义,提升开发效率 同样的原理,我们也可以下载别人写好的模块然后导入到自己的项目中使用,这种拿来主义,可以极大地提升我们的开发效率 ps:
如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行,此时test.py被称为脚本script。
3.怎么导入模块
比如我需要记录当前程序执行的时间,那么就会在我的文件的开头调用一个叫做time的东西,这个time就是一个时间模块,这个模块里有大量对时间进行相应处理的功能操作,
1.import +模块名(这里不能再加模块文件的后缀)
重点:当你在一个执行文件中导入了其他文件的(模块)时,发生了三件事:1.被导入的模块加载到内存,创建一个模块的名称空间。2.执行模块内对应的所有代码语句,并将期间产生的名字(变量名,函数名等)存放于模块文件所在的名称空间里3.在调用模块的执行文件的名称空间中拿到模块名,该模块名字指向模块文件所产生的名称空间(这里就相当于模块名是一个变量名,指向的是模块内部对于的代码,只不过这里是两个不同的名称空间,一个是执行文件产生的,一个是模块产生的,二者是独立的,只是通过一个模块名来起到一个链接桥梁的作用)。也就是说模块里面定义的变量或函数名是不会受到执行文件中变量名函数名的影响的,哪怕是你模块里面有个变量值为1,执行文件里面又定义了一个相同的变量值为2,这个时候你调用模块,并选择打印变量值,显示的值为1.
这个就相当于之前学到的函数一样,函数里面的变量的作用域在函数定义阶段就已经确定下来了,不会随着函数调用位置的变化而变化,也就是说无论你在哪调用函数,函数都会回到初始定义阶段按照初始定义阶段的作用域及规则来执行
2.第二种方式:from+模块名import+模块内想要导入的函数或者变量名
第二种方法优势在于,在后续调用模块内的内容时,不需要再在前面加上模块名这个前缀。用这个方法调用模块时,也发生了三件事:1.创建模块名称空间,2.执行模块内需要被引用的代码段,将产生的名字存放于模块的名称空间中3.第三点与import导入时的方法有点不一样,执行文件的名称空间中会存放import后面跟的名字,当然只是一个名字,与模块名一样,这样在调用模块某段功能时,就可以直接调用了,这个时候就会在执行文件名称空间中直接拿到这个名字,再根据这个名字去模块名称空间里找到对应的代码块。
导入多个函数 或变量名 from+模块名import+函数,变量名,。。。。
4.模块的改名
有时候会遇到导入的模块名特别长的情况,这个时候我们可以对其进行再赋值也就是给他换个名字,这样可以方便后续的引用操作
import time as t
from spam import func as f
5.from 模块名 import *
这句话的意思是将模块内所有的名字全部加载到执行文件所创建的名称空间中,这样就可以实现所有的名字均可直接调用的效果。但是这样也会造成一个隐患,第一你不知道你导入的这个模块里到底有多少代码块,第二,你不知道模块里已经命名了哪些名字,这样就可能产生混用名字的情况
6.站在模块的编写者的角度
模块的编写者也不可能一次性就能将所写的代码写到零bug无报错的情况,那么这个时候必定需要对自己所写的代码进行相应的调试,但是导入模块的调用者又需要调试模块的代码,这里对于模块的编写者,能不能有一种方法可以让模块文件在自身被执行时运行一部分代码,在被调用时运行另一部分代码呢?
python中确实有这样一种内置的方法.__name__该方法每个py文件都有,它的效果就是,当文件自身被当作脚本运行时,它输出的结果是__main__而如果它是被当作模块被倒入的话,它的输出结果就会变成模块名,这样的话对应模块编写者就可以通过
if __name__=='__main__':
print('执行调试代码‘)
else:
print('执行写好将被导入使用的代码’)
7.导入模块时,查找模块文件路径的顺序
路径顺序肯定是:内存---->内置空间----->sys.path(第一个路径一定是当前执行文件所在的文件夹)
记死这个顺序!当我们要导入的模块不在执行文件的当前目录,这个时候只需将其添加到sys.path内即可正常导入使用,
8.模块在第一次被导入时,就会被加载到内存,之后如果紧跟几个一样的导入语句,所导入的模块只会被内存加载一次,之后的导入相当于直接从内存中找寻, 避免了内存空间的浪费,而且当你将模块导入后,将模块文件删除,在执行文件没有结束的情况下,再次调用模块,还是可以导入的,这个时候其实就是从内存中调用的,而当执行文件程序结束,再次调用就没有了,因为内存已将加载的内清空了
#1、从文件级别组织程序,更方便管理 随着程序的发展,功能越来越多,为了方便管理,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理。这时我们不仅仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用 #2、拿来主义,提升开发效率 同样的原理,我们也可以下载别人写好的模块然后导入到自己的项目中使用,这种拿来主义,可以极大地提升我们的开发效率 #ps: 如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行,此时test.py被称为脚本script。
9.循环导入模块
简而言之就是两个模块相互导入,多用于程序补丁。
举列
模块m1和模块m2相互导入
m1模块
模块2 执行文件
输出结果
*************************
正在导入m1
正在导入m2
来自与m2的y: m2
来自m1的x: m1
*************************
总结:把导入语句 可以放在def定义函数下,实现相互导入 (因为函数在定义阶段不执行,导入语句也不执行)