20190926 模块
目录
模块
1.什么是模块
模块是一系列功能的集合体,是一堆函数的集合体。一个.py文件也可以看成一个模块。
2.模块的四种形式
- 内置模块:使用C编写并连接到python解释器的内置模块
- 第三方模块:已被编译为共享库或DLL的C或C++扩展,pip安装
- 自定义模块:自己写了一个.py文件,里面的函数就可以调用
- 包:把一系列模块组织到一起的文件夹
3.模块的作用
实现功能比代码更方便
模块的导入
1.import +模块名
import + 模块名可以直接导入模块,在导入的同时发生了三件事
- 开辟内存空间,空间就命名就是为模块的名字
- 把模块中的所有代码读入名称空间,然后运行
- 通过模块.方法名使用模块中的方法
import time
time.sleep(0.01)
2.form ... import...
from + 模块名 + import + 方法名
- 开辟内存空间,内存名为模块名
- 把模块中的所有代码读入名称空间,然后运行
- 把方法读入文件代码中,因此可以直接使用方法名
from time import sleep
sleep(0.01)
优点:不用加前缀,代码更加简洁
缺点:容易与当前执行文件中名称空间中的名字冲突
3.from ... import *
from + 模块名 + * 导入所有的功能
from time import *
time()
localtime()
gmtime()
4.优缺点
import +模块名 与 from...import 的
相同点:
- 两者都会执行模块对应的文件,两者都会产生模块的名称空间
- 两者调用功能时,需要跑到定义时寻找作用域关系,与调用位置无关
不同点
- import需要加前缀;from...import...不需要加前缀
# import
## 优点: 永不冲突
## 缺点: 每次导入多输入几个字符,非常麻烦
# from...import...
## 优点: 少输入几个字符
## 缺点: 容易发生冲突
5.自定义模块
分文件存储代码,函数与函数之间分开,让代码更清晰,不同模块不同事
__all
__方法
可以使自定义模块内的变量指定打印,只会搜索__all__ []
内的对象
# run.py
from spam import money
money = 10
print(money) # 10
---------------------------------------------------
# spam.py
__all__ = ['money', 'read1'] # 只允许导入'money'和'read1'
----------------------------------------------------
# run.py
from spam import *
# 导入spam.py内的所有功能,但会受限制于__all__
循环导入
两个文件,各在文件中导入对方,
# m1.py
from m2 import x
y = 'm1'
print('from m1.py')
# m2.py
from m1 import y
x = 'm2'
print('from m2.py')
会发生报错,不断地调用创建内存空间(每个内存空间只创建一次)
首先执行
m1 ==》from m2 import x ==》 m2 ==》from m1 import y ==》print('from m1.py') ==》print('from m2.py') ==》print('from m1.py')
解决方案
我们可以使用函数定义阶段只识别语法的特性解决循环导入的问题,我们也可以从本质上解决循环导入的问题,但是最好的解决方法是不要出现循环导入。
- 打印结果在导入模块之上
# m1.py
print('from m1.py')
y = 'm1'
from m2 import x
-------------------------------------------
# m2.py
print('from m2.py')
x = 'm2'
from m1 import y
- 利用函数定义阶段只时代语法不执行代码,最后执行函数
# m1.py
def f1():
from m2 import y
print('m1:', x, y)
x = 10
f1()
----------------------------------------------------------
# m2.py
def f2():
from m1 import x
print('m2:', x, y)
y = 20
f2()
模块搜索路径的顺序
模块其实就是一个文件,想要执行文件,先要找到模块的路径
如果模块的文件路径和执行文件不在同一个文件目录下,我们就需要指定模块的路径。
模块的搜索路径指的就是导入模块时需要检索的文件夹。
导入模块时查找顺序是: 内存 - 内置 - 自定义
- 先从内存中已经导入的模块中查找
- 内置的模块
- 环境变量 sys.path 中查找
python文件的两种用途
python文件总共有两种用途,一种是执行文件,另一种是当做模块导入
- 脚本,文件是整个程序,用来被执行
- 模块,文件中存放功能,用来被导入
__name__
方法
用于标识所在模块的模块名,当前运行的程序,其 _name_ 的值为 main,而导入到当前程序中的模块,其 _name_ 值为自己的模块名。
# using_name.py
if __name__ == '__main__':
print('程序自身在运行')
else:
print('我来自另一模块')
'''运行输出为:程序自身在运行'''
# 同一文件夹下另一文件
import using_name
# 运行输出为:我来自另一模块
当文件被执行是即当做执行文件的时候__name__ == '__main__'
当文件作为模块文件 __name__
== 文件名
pyinstaller 模块
可以让py文件封装为.exe软件
pyinstaller –i rose.ico –F rose.py
# 使用这个模块压根不需要导入
# http://www.bitbug.net/?tdsourcetag=s_pcqq_aiomsg
# pyinstaller –i rose.ico(图片文件,百度转一个) –F rose.py(python文件)
# pyinstaller –i rose.ico –F rose.py
# 把.py文件转成.exe