模块

1 每个py文件就是一个模块
2 自我感觉就是一个或多个py文件被当做模块导入到另一个文件,在另一个文件中引用py文件中的某些功能

为什么要用模块

1 为了写的代码可以重用,不至于把所有的代码卸载一个文件内,当项目规模小的时候,一个py文件就可以搞定,
2 但是如果是一个非常大的项目,就必须把相关功能进行分离,方便我们日常维护和新项目的开发

import加载的模块一共分成四个通用类别:

1 .使用python编写的PY文件
2 .已被编译为共享库或者DLL或者C或者C++的扩展
3 .包
4 .使用C编写并连接到python解释器的内置模块

导入模块的方式:
1.import 模块名
2.from 模块名 import 函数名(方法名)

import方式导入

1 自定义一个模块module.py
 2 print('这里是py文件module的开始')
 3 name = 'bob'
 4 address = '上海'
 5 
 6 def play():
 7     print(f'{name}去了{address}迪士尼')
 8 
 9 print('这里是py文件module的结束')
10 
11 
12 在另外一个文件test3中引用这个模块
13 #此时我们已经导入了一个自定义模块module并重命名这个模块为modu(as的功能为重命名模块名)
14 #但这里pycharm报错,并不是python报错,因为pycharm找不到这个模块
15 #导入模块的时候,会把模块中的代码执行了一遍
16 import module as modu
17 def func():
18     print('hello world')
19 
20 print(modu.name)
21 print(modu.address)
22 
23 func()          #自己这个文件中的方法
24 modu.play()     #模块中的方法
25 结果
26 这里是py文件module的开始
27 这里是py文件module的结束
28 bob
29 上海
30 hello world
31 bob去了上海迪士尼
32 
33 注意: 由于模块在导入的时候会创建其自己的名称空间,所以在使用模块中的变量的时候一般是不会产生冲突的

一个文件中多次导入同一个自定义模块

1 import module
2 print('hhhhhhh')
3 import module   #如果已经导入过该模块,此时不会再执行模块中的代码了
4 import module
5 import module
6 结果
7 这里是py文件module的开始
8 这里是py文件module的结束
9 hhhhhhh

导入模块的过程:
1. 去判断当前正在导入的模块是否已经倒入过
2. 如果已经导入过,不会重新导入该模块
3. 如果没有导入过,首先开辟一个内存空间
4. 把该模块中的代码放在新开辟的空间中,运行该模块中的代码
5. 把该文件的名字作为当前名称空间的名字(前提是没有as)

查看已经导入的模块

1 import sys
2 print(sys.modules.keys())
3 或
4 print(globals())    #查看模块的名称空间

模块导入顺序:
1. 先导入内置模块
2. 第三方模块
3. 自定义的模块

1 事例1
 2 import module as modu
 3 print(modu.name)       #应用的是模块中的name变量
 4 
 5 modu.name = '攻城狮'   #从另一个模块中改变应用的模块中变量的值
 6 modu.play()            #所以模块中的name变量值改变为修改后的'攻城狮'
 7 print(modu.name)
 8 结果
 9 这里是py文件module的开始
10 这里是py文件module的结束
11 bob
12 攻城狮去了上海迪士尼
13 攻城狮
14 
15 
16 事例2
17 import module as modu
18 print(modu.name)    #打印的是模块中的name变量
19 
20 def func():
21     global name     #此时在文件中开辟了一个name变量的内存空间
22     name = '佩奇'   #把全局变量name内存空间赋值为'佩奇'
23     modu.play()     #打印模块中的play方法
24 func()
25 modu.play()         #文件中gloal的全局变量name并不影响模块中name变量的值
26 print(name)         #这里打印的是此文件中全局name变量(并不是模块中的变量)
27 结果
28 这里是py文件module的开始
29 这里是py文件module的结束
30 bob
31 bob去了上海迪士尼
32 bob去了上海迪士尼
33 佩奇
34 
35 
36 事例3
37 vim module.py
38 print('这里是py文件module的开始')
39 name = 'bob'
40 address = '上海'
41 
42 def play():
43     global  name        #global 引用当前模块的全局
44     name = '贝塔'       #模块中全局变量修改为'贝塔'
45     print(f'{name}去了{address}迪士尼')
46 
47 print('这里是py文件module的结束')
48 
49 import module as modu
50 name = '佩奇'
51 
52 modu.play()
53 print(modu.name)   #返回的是模块中修改后的name变量值
54 
55 print(name)     #并没有改变文件内的name变量值
56 结果
57 这里是py文件module的开始
58 这里是py文件module的结束
59 贝塔去了上海迪士尼
60 贝塔
61 佩奇
62 
63 
64 也可以用import一次性导入多个模块(不建议这样用)
65 import module as modu,test2,time,os,...
66 modu.func()
67 test2.mode()
68 结果
69 我是模块1
70 我是模块2

模块测试: 要运行这个py的时候才执行代码
如果在模块中定义__name__ == __main__,作用就是测试模块中的某些功能
所以别的文件调用不了此模块中的方法,但单独执行这个模块可以执行这个模块中的方法

1 name = 'bob'
2 address = '上海'
3 def play():
4     print(f'{name}去了{address}迪士尼')
5 
6 if __name__ == '__main__':      # 当前文件如果是启动文件就执行
7     print('这里是py文件module的开始')
8     play()
9     print('这里是py文件module的结束')

from方式导入模块: 导入的只有一个功能

1 vim module.py
 2 def func1():
 3     print('我是模块中的方法一')
 4 
 5 def func2():
 6     print('我是模块中的方法二')
 7 
 8 vim test.py
 9 from module import func1
10 func1()
11 结果
12 我是模块中的方法一
13 
14 
15 from module import func1
16 func1 = '定义的变量与导入的模块中的方法重名则会覆盖模块中的方法'
17 print(func1)
18 结果
19 定义的变量与导入的模块中的方法重名则会覆盖模块中的方法

总结
如果当前文件中出现了重名的变量时,会覆盖掉模块引入的那个变量
所以创建的py文件的名字不要和系统内置的模块重名

 

包的定义:

1 包实际就是文件夹,包内可以写很多个模块
2 注意,在python2中规定,包内必须存在__init__.py文件,创建包的目的不是为了运行,
3 而是被导入使用,包只是一种形式而已,包的本质就是一种模块
4 自我理解
5 1.只要是文件夹就是包,
6 2.文件夹里边的py文件就是模块,
7 3.文件(模块)中的方法就是包中某个模块的方法
8 4.调用,包名.模块名.模块中的方法名(函数)

按照代码从小到大的顺序排列:

1 一个表达式 -> 一条语句  -> 语句块  -> 函数 -> 类  -> 模块  -> 包  -> 项目

__init__.py文件说明

1 在__init__.py文件中分别去引用所在目录(子包)中的内容
2 作用其实就是在文件中导入子包(此目录的下一级目录)或者模块名

导入包方法

1 import 包名.模块名.方法
2 from 包名 import 模块名
3 调用 模块.方法

包导入分类

1 绝对导入: 从顶级包开始导入的
2 相对导入: 用.或..作为起始位置的(在包内部可以使用)
3 from ..包名 import 模块名
4 
5 程序对包或模块的查找路径是:sys.path,跟着你的启动文件所在的位置变化
6 无论使用绝对导入,还是相对导入,启动文件一定要放在最外面
7 注意
8 在pytho中不允许运行的程序导包的时候超过当前顶级包的范围(相对导入),如果使用绝对导入,没有这个问题
9 在导包出错的时候,一定要先导入sys模块,先看sys.path,看一下是否真的能获取到包的信息