Python之第二十九天的努力--自定义模块,json、pickle、hashlib模块
03 自定义模块
-
模块是什么?
如: 抖音:20万行代码全部放在一个py文件中?
为什么不行?
- 代码太多,读取代码耗时太长。
- 代码不容易维护。
所以要?
一个py文件拆分若干个文件,这些文件有没有相似相同的功能。冗余。此时要将这些文件中相似或相同的函数提取出来,input 功能,print 功能,time.time()......放在一个文件中,当你想用这个功能时拿来即用。类似于这些py文件:常用的相似的功能集合。
模块就是一个py文件
-
为什么要有模块?
- 拿来主义,提高开发效率。
- 便于管理维护。
- 什么是脚本?
- 脚本就是py文件,长期保存代码的文件。
-
模块的分类
- 内置模块200种左右,Python解释器自带的模块,time os sys hashlib等等
- 第三方模块6000种,一些大牛写的,非常好用的。pip install 需要这个指令安装的模块,Beautiful_soup,request,Django,flask 等等...
- 自定义模块,自己写的一个py文件。
-
import的使用
import 一个模块先要干什么?
import tbjx 执行一遍tbjx这个模块里面的所有代码,第一次引用tbjx 这个模块,会将这个模块里面的所有代码加载到内存,只要你的程序没有结束,接下来你引用多少次,它会先从内存中查找有没有此模块,如果已经加载到内存了,就不在重复加载。
-
第一次导入模块执行三件事
- 1.在内存中创建一个以tbjx命名的名称空间。
- 2.执行此名称空间所有的可执行代码(将tbjx.py文件中的所有变量与值的关系加载到这个名称空间)。
- 3.通过tbjx. 的方式引用模块里面的代码。
-
被导入模块有独立的名称空间
# # name = 'zs' # print(name) # zs # print(tbjx.name) # 太白金星 # # def read1(): # print(666) # tbjx.read1() # tbjx模块: 太白金星 # name = 'zs' tbjx.change() print(name) # zs print(tbjx.name) # barry -
为模块起别名
-
1.简单,便捷。
-
2.有利于代码的简化。
-
# 了解 # 原始写法 # result = input('请输入:') # if result == 'mysql' : # import mysql1 # mysql1.mysql() # elif result == 'oracle': # import oracle1 # oracle1.oracle() # 起别名 result = input('请输入:') if result == 'mysql' : import mysql1 as kk elif result == 'oracle': import oracle1 as kk kk.db() # 统一接口,归一化思想
-
-
导入多个模块
# import time,os,sys # 这样写不好 import time import os import sys
-
-
from...import...
-
from...import... 的使用
from tbjx import name from tbjx import read1 from tbjx import read2 print(name) print(globals()) -
from...import...与import 对比
-
from...import...用起来更方便
-
from...import... 容易与本文件的名字产生冲突,后者把前者覆盖。
from tbjx import name name = 'zs' print(name) # zs name = 'zs' from tbjx import name print(name) # 太白金星# from tbjx import read1 name = 'zs' read1() # tbjx模块: 太白金星 ''' tbjx.py 部分代码: name = '太白金星' def read1(): print('tbjx模块:',name) '''
-
-
一行导入多个
from tbjx import name,read1 # 不建议这样写 from tbjx import name from tbjx import read1
-
-
from ... import *
from tbjx import * # 千万别这么写,必须要将这个模块中的所有名字记住 # 但是可以配合一个变量使用 __all__ ''' # __all__ = ['name','read1'] # 配合*使用 ''' # read2() # 报错 # from tbjx import read2 # read2() -
py文件的两种功能
-
1.自己用 脚本
-
2.被别人引用 模块使用
-
# print(__name__) # __main__ # 当做脚本:__name__ == __main__ 返回True # 当 tbjx.py 做模块被别人引用时:__name__ == tbjx # __name__ 根据文件的扮演的角色(脚本,模块)不同而得到不同的结果 # 1.模块需要调试时,加上 if __name__ == '__main__': if __name__ == '__main__': change() # 2.作为项目的启动文件需要用
-
-
模块的搜索路径
-
import kk
- 它会先从内存中寻找有没有已经存在的以kk命名的名称空间。
- 它会从内置的模块中找,time,os,sys...
- 它从sys.path中寻找 可往里添加路径
# 模块的搜索路径: # import tbjx # print(tbjx.name) # Python 解释器会自动将一些内置内容(内置函数,内置模块)加载到内存中。 # import sys # print(sys.path) # 第一个路径是 当前执行文件的相对路径 # 添加其他路径下的模块 操作sys.path # import sys # sys.path.append(r'路径')
-
02 json pickle 模块
序列化模块:将一种数据结构(list,tuple,dict ....)转化成特殊的序列。
为什么存在序列化?
数据 ---> bytes
只有字符串类型和bytes可以互换。
dict,list.... ----> str <----> bytes
数据存储在文件中,str(bytes类型)形式存储,比如字典。
数据通过网络传输(bytes类型),str 不能还原回去。
特殊的字符串:序列化
json模块 : (重点)
- 不同语言都遵循的一种数据转化格式,即不同语言都使用的特殊字符串。(比如Python的一个列表[1, 2, 3]利用json转化成特殊的字符串,然后在编码成bytes发送给php的开发者,php的开发者就可以解码成特殊的字符串,然后在反解成原数组(列表): [1, 2, 3])
- json序列化只支持部分Python数据结构:dict,list, tuple,str,int, float,True,False,None
pickle模块:
- 只能是Python语言遵循的一种数据转化格式,只能在python语言中使用。
- 支持Python所有的数据类型包括实例化对象。
-
json:将数据结构转化成特殊的字符串,并且可以反转回去。
import json dic = {'username':'zs','password':123,'status':True} # dumps loads 主要用于网络传输,但是也可以读写文件 # 特殊的字符串 # st = json.dumps(dic) # print(st,type(st)) # 反转回去 # dic1 = json.loads(st) # print(dic1,type(dic1)) # 读写文件 # l1 = [1,2,3,{'name':'zs'}] # 转化成特殊的字符串写入文件 # with open('json文件',encoding='utf-8',mode='w') as f1: # st = json.dumps(l1) # f1.write(st) # # 读取出来还原回去 # with open('json文件',encoding='utf-8') as f2: # st = f2.read() # l2 = json.loads(st) # print(l2,type(l2)) # [1, 2, 3, {'name': 'zs'}] <class 'list'> # dump load 只能写入文件,只能写入一个数据结构 # l1 = [1,2,3,{'name':'zs'}] # with open('json文件2',encoding='utf-8',mode='w') as f1: # json.dump(l1,f1) # 读取数据 # with open('json文件2',encoding='utf-8') as f2: # l2 = json.load(f2) # print(l2,type(l2)) # [1, 2, 3, {'name': 'zs'}] <class 'list'> # 一次写入多个数据怎么做? # 绝对不能使用 dump load # 使用 dumps loads dic1 = {'name':'zs'} dic2 = {'name':'ls'} dic3 = {'name':'ww'} # 写入 # with open('json文件3',encoding='utf-8',mode='w') as f1: # f1.write(json.dumps(dic1) + '\n') # f1.write(json.dumps(dic2) + '\n') # f1.write(json.dumps(dic3) + '\n') # 读取 with open('json文件3',encoding='utf-8') as f2: for line in f2: print(json.loads(line)) -
pickle:只有Python才有的。
l1 = [1,2,3,{'name':'zs'}] import pickle # dumps loads 只能用于网络传输 # st = pickle.dumps(l1) # print(st) # # # l2 = pickle.loads(st) # print(l2,type(l2)) # dump load 直接写入文件,可写入多个数据 dic1 = {'name':'zs'} dic2 = {'name':'ls'} dic3 = {'name':'ww'} # 写入 # with open('pickle文件',mode='wb') as f1: # pickle.dump(dic1,f1) # pickle.dump(dic2,f1) # pickle.dump(dic3,f1) # 读取 # with open('pickle文件',mode='rb') as f2: # print(pickle.load(f2)) # print(pickle.load(f2)) # print(pickle.load(f2)) # 写入一个对象 def func(): print('in func') # with open('pickle对象',mode='wb') as f1: # pickle.dump(func,f1) with open('pickle对象',mode='rb') as f2: print(pickle.load(f2))
03 hashlib模块
-
包含很多加密算法。MD5,sha1 sha256 sha512......
-
用途:
- 密码加密。不能以明文的形式存储密码,密文的形式。
- 文件的校验。
-
用法:
- 将bytes类型的字节转化成 固定长度的16进制数字组成的字符串。
- 不同的bytes利用相同的算法(MD5)转化成的结果一定不同。
- 相同的bytes利用相同的算法(MD5)转化成的结果一定相同。
- hashlib算法不可逆(MD5中国王晓云破解了)。
-
# import hashlib # 普通加密 # md5 # s1 = 'aaaccckkkdddwww哈哈哈哈' # import hashlib # ret = hashlib.md5() # ret.update(s1.encode('utf-8')) # print(ret.hexdigest()) # e97b504cd21c20a0dbd716179b453694 # 加盐 # s1 = 'aaaccckkkdddwww哈哈哈哈' # import hashlib # ret = hashlib.md5('kkkk'.encode('utf-8')) # ret.update(s1.encode('utf-8')) # print(ret.hexdigest()) # 9c559c19abc56c29d45f290427e323e4 # 动态的盐 # s1 = 'aaaccckkkdddwww哈哈哈哈' # import hashlib # ret = hashlib.md5('kkkk'[::2].encode('utf-8')) # ret.update(s1.encode('utf-8')) # print(ret.hexdigest()) # 55318a80fdeb7a3301dd982d34fe3924 # sha系列: 对安全级别要求高的才使用。 # 随着sha 系列数字越高,加密越复杂,越不易破解,但是耗时越长。 # s2 = '20000514' # import hashlib # ret = hashlib.sha256() # ret.update(s2.encode('utf-8')) # print(ret.hexdigest()) # # abb8cdb29b9fab5777ced0fd223edcebd2cb92dce5a29ec95b55430e0d59da27 # 文件的校验 # Linux中一切皆文件:文本文件,非文本文件,音频,视频,图片.... # 无论下载的视频,还是软件(国外的软件),往往都会有一个md5值 # 对比md5 值是否相同 # 文件过大时 可拆解 # s1 = 'aaaccckkkdddwww哈哈哈哈' # import hashlib # ret = hashlib.md5() # ret.update(s1.encode('utf-8')) # print(ret.hexdigest()) # e97b504cd21c20a0dbd716179b453694 # s1 = 'aaaccckkkdddwww哈哈哈哈' # import hashlib # ret = hashlib.md5() # ret.update('aaa'.encode('utf-8')) # ret.update('ccc'.encode('utf-8')) # ret.update('kkk'.encode('utf-8')) # ret.update('ddd'.encode('utf-8')) # ret.update('www'.encode('utf-8')) # ret.update('哈哈哈哈'.encode('utf-8')) # print(ret.hexdigest()) # e97b504cd21c20a0dbd716179b453694 # 相关练习 # import hashlib # def MD5(pwd): # ret = hashlib.md5() # ret.update(pwd.encode('utf-8')) # return ret.hexdigest() # # # def register(): # username = input('请输入用户名:').strip() # password = input('请输入密码:').strip() # password_md5 = MD5(password) # with open('register',encoding='utf-8',mode='a') as f1: # f1.write(f'{username}|{password_md5}\n') # # # def login(): # username = input('请输入用户名:').strip() # password = input('请输入密码:').strip() # # # register()

浙公网安备 33010602011771号