Python课程回顾(day15)
模块
1.什么是模块
模块就是在多个文件内分别存放不同的功能,存放功能的文件就叫做模块,而模块之间是可以相互导入调用的
2.为什么要有模块
我们通过之前学过的语法和理论已经可以实现去编写一个个的小程序了,并且我们在学习了函数之后我们的代码的各个性能都有多提高,那么模块既然也是存放功能,并且还要用多个文件,那么为什么要学模块呢?
通过之前我们写过的ATM+购物车可以明确的感受到多个功能存放在一个文件内的缺点:
代码冗余脏乱 :整篇下来的ATM+购物车纯代码都要好几百行,函数也需要很多,看起来就非常不美观
可读性差 :从上倒下依次看下去会影响整体逻辑思维,函数与函数之间的交互越多,可读性越差
可扩展性差 :不能轻易的添加或修改源代码,牵一发而动全身说的就是这种情况
可处理问题性差:代码出错要一层层的去找原因,代码越多,处理问题越困难
所以这个时候我们就需要使用到模块,将一个个的功能存放于一个个文件内,并且不影响文件之间的导入与调用
3.模块的分类
自定义模块:即我们自己创建一个文件然后将功能写入到文件的模块
内置模块 :是Python解释器中自带的模块,是使用C语言编写的
第三方模块:也属于自定义模块,不过是其他程序员已经编写好的模块,可以直接下载使用
已经编译为DLL,C或C++的模块:这种模块我们不需要知道它的来历,只需要根据需求下载导入即可
4.如何使用模块
简单来说使用模块就是在一个模块内,完成导入调用其他模块的一种操作,所以我们一定要遵循一个原则,那就是无论是内置模块还是自定义模块,一定要先导入,后使用
使用import将模块导入到另一个py文件中
import 与 from...import...语法(导入)
import:
使用一个使用模块来将另外一个被导入模块导入到当前使用模块内
1.那么在执行import时到底发生了什么?
根据我们之前学过的名称空间:
1. 创建一个命名空间
2.执行导入的Py文件,将产生的名称放入名称空间
3.在执行文件中产生一个新的名称,该名称指向被导入的名称空间
2.需要注意的是:若多次导入相同的模块到当前文件,则只会执行一次
例:
import spam
import spam
import spam
import spam
只会执行一次spam模块
3.执行文件与被导入文件的命名空间是相互独立的
例:
在func中导入spam文件 spam文件内容 money = 100 def salary(): print('money') 在func中执行内容 import spam money = 1000 spam.salary() 输出结果为100 模块中代码的执行始终以当前文件的命名空间为准
4.import语句的多种写法
取别名:将导入的模块命名一个新的名称方便使用 (import spam as newspam)
导入多个模块:一次性将要用到的模块全部导入 (import spam,sys,time....)
导入模块中某个名字到当前命名空间:(from spam import func # 在当前命名空间可直接不加前缀调用spam的func函数)
from取别名:等同于import取别名 (from spam import func as f)
from导入多个模块:from spam import func,money,age....
from导入模块中所有名称:from spam import * (若要导入的模块内的名字较多的情况下不建议使用,易产生名字冲突)
在被导入模块中可以使用__all__选择可以被导入的名称,__all__是一个列表,没有在列表内的名称均可以被导入(列表内的值是字符串类型)
Python文件执行的两种方式
1.作为文件被导入
2.作为执行文件执行
为了区分文件究竟是执行文件还是作为模块被导入,我们可以使用__name__与__main__来进行一个判断:
if __name__ == __main__: print('执行文件') else: print('被导入的模块')
模块的搜索顺序
基于我们刚才所做的一系列测试,我们能够导入模块成功的原因是我们所导入的模块文件就在我们当前的文件夹内,那么我们以后不可能会一直将所有文件都放在一个文件夹内,那么这个时候我们应该如何去找呢?
我们首先要知道python查找模块时的顺序:
首先--->在内存中已加载好的模块--->python中的内置模块--->在sys.path(系统环境变量)
我们首先看一下sys.path下有哪些路径
import sys for line in sys.path: print(line) C:\Users\Administrator\PycharmProjects\chree\Daily exercises C:\Users\Administrator\PycharmProjects\chree 这里的项目目录是pycharm自己加上去的,当它不存在。 E:\4期python C:\Users\Administrator\AppData\Local\Programs\Python\Python36\python36.zip C:\Users\Administrator\AppData\Local\Programs\Python\Python36\DLLs C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib C:\Users\Administrator\AppData\Local\Programs\Python\Python36 C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages E:\Program Files\JetBrains\PyCharm 2018.2.2\helpers\pycharm_matplotlib_backend
接下来我们验证内存和内置的顺序
创建两个模块 m1.py文件内容 def f1(): pass time.py文件内容 print('this is time) 在使用模块.py文件导入这两个模块 import m1 mi.fi() import time 在sleep期间删除m1文件,m1文件此时已经加载到内存所以不会报错 time.sleep(10) 但重新运行文件时就会报错 import m1 mi.f1()
import sys
print(sys.modules)
print('time' in sys.modules)
此处结果为False证明内置优先于sys.path中自定义的
import time
time.sleep(2) 而导入time文件则会直接导入内置time模块 证明内置是优先于sys.path中自定义的
结论:
1.以后在我们写模块时,一定不要让自己的模块名与内置或者第三方的模块名发生冲突。
2.对于以后查找模块路径,我们不能对内存和内置的模块进行操作,那么我们就只能在sys.path中手动添加自己需要的模块
import sys
sys.path.append('模块的文件路径')
内置函数
1.abs() #绝对值 2.all() #类似布尔类型的and 传入的值必须都为True才为True 3.any() #类似布尔类型的or 传入的值只要有一个True就为True 4.asscII() #等同于str(),将传入的值返回成字符串类型,中文则会转成assII编码 5.bin() #二进制 6.oct() #八进制 7.hex() #十六进制 8.bool() #判断,返回布尔值 9.bytearray() #将参数转换成字节 10.bytes() #同上 11.callable() #查看参数内的值是否可以调用,返回布尔值 12.chr() #可以将整数转换为Unicode字符 13.ord() #将Unicode字符转换为整数 14.eval() #执行代码并返回执行结果 15.exec() # 执行代码不返回任何结果