一、模块
问:什么是模块?
答:模块就是一系列功能的结合体
模块的三种来源:
1.内置的(python解释器自带)
2.第三方的(别人写的)
3.自定义(你自己写的)
模块的第四种表现形式:
1.使用python编写的py文件(也就意味着py文件也可以称之为模块:一个py文件也可以称之为一个模块)
2.已被编译为共享库或dell的c或c++扩展
3.把一系列模块组织到一起的文件夹(文件夹下有一个__init__.py文件,该文件夹称之为包)
包:一系列py文件的结合体
4.使用C编写并连接到python解释器的内置模块
为什么使用模块:
1.用别人写好的模块(内置的,第三方的):典型的拿来主义,极大的提高开发效率
2.使用自己写的模块(自定义的):当程序比较庞大的时候,你的项目不可能只在一个py中,那么当多个文件中都需要使用相同的方法的时候,可以将公共的方法写到一个py文件中,其他的文件以模块的形式导过去直接调用即可
使用模块的时候一定要注意区分那个是执行文件,哪个是被导入文件
二、import
1.import模块导入
模块可以包含执行的语句和函数的定义,这些语句的目的是初始化模块,他们只在模块第一次遇到导入import语句时才执行(import语句是可以在程序中的任意位置使用的,且针对同一个模块。为了防止你重复的导入,python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载到内存中的模块对象增加了一次引用,不会重新执行模块内的语句)
1 print('from the zzj.txt') 2 name = 'zzj' 3 4 def read1(): 5 print('zzj模块:',name) 6 7 def read2(): 8 print('zzj模块') 9 read1() 10 11 def change(): 12 global name 13 name = 'gentleman'
1 import zzj 2 print(zzj.read1)#运行zzj.py文件中的read1函数 3 zzj.change() 4 print(zzj.name)
总结:
1.只要你能拿到函数名,无论在哪都可以通过函数名加括号来调用这个函数(会回到函数定义阶段依次执行代码)
2.函数在定义阶段,名字的查找关系就已经固定死了,不会因为调用的位置而改变。
PS: import支持一行导入多个模块,但是不推荐。当几个模块没有里联系的情况下,应该分多次导入。通常情况下,模块的句式会写在文件开头。
2.form…import…导入模块
利用from…import…句式
1.访问模块中的名字不需要加模块名前缀
2.在访问模块中的名字可能会与当前执行文件中的名字冲突
form md1 import* #一次性将md1模块中的名字全部加载出来,但是不推荐使用
__all__可以指定当所在py文件被当做模块导入的时候,可以限制导入者能够拿到的名字个数。
3模块循环导入问题
1 创建一个m1.py 2 print('正在导入m1') 3 from m2 import y 4 5 x='m1' 6 7 创建一个m2.py 8 print('正在导入m2') 9 from m1 import x 10 11 y='m2' 12 13 创建一个run.py 14 import m1 15
报错原因:首先执行run.py >>> 执行import m1,开始导入m1并运行其内部代码>>>打印内容‘正在导入m1’>>>执行 from m2 import y>>>开始导入m2并运行其中的代码>>打印内容‘正在导入m2’>>>执行from m1 import x,因为m1已经执行过了,所以直接去m1中拿,然而此时 x并没有存在于m1中,所以报错。
解决方法:
1 创建一个m1.py 2 print('正在导入m1') 3 x='m1' 4 from m2 import y 5 6 创建一个m2.py 7 print('正在导入m2') 8 from m1 import x 9 10 y='m2' 11 12 创建一个run.py 13 import m1
4.区分py文件的类型
1 #创建 md.py 2 def index1(): 3 print('index1') 4 def index2(): 5 print('index2') 6 print(__name__) 7 #当文件被当做执行文件执行的时候__name__打印的结果是__main__ 8 #当文件被当做模块导入的时候__name__打印的结果是模块名(没有后缀)
5.模块的查找顺序
1.先从内存中找
2.内置中找
3.sys.path中找(环境变量)
6.绝对导入与相对导入
绝对导入必须依据执行文件夹路径所在的文件夹为准
相对导入不能在执行文件中使用
相对导入只能在被导入的模块中使用,使用相对导入,就不需要考虑执行文件到底是谁。只需要知道模块与模块之间的路径关系
. 代表的当前路径
.. 代表的上一级路径
... 代表的是上上一级路径