python's twenty-fifth day for me 模块
模块:
py文件就是模块。
python之所以好用,因为模块多。
内置模块:python安装的时候自带的。
扩展模块:别人写好的,需要安装后可直接使用。
自定义模块:自己写的模块。
序列化模块:
能存储在文件中的一定是字符串或者字节,能在网络上传输的只有字节。
序列化:就是创造一个序列(字符串)。
python中的序列化模块:
json:所有的编程语言都通用的序列格式。
它支持的数据类型非常有限,数字,字符串,列表,字典。
pickle:只能在python语言的程序之间传递数据用的。
pickle支持python中的所有数据类型。
shelve:python3x之后才有的。
json模块:识别不了元祖类型,会将元组类型直接转换成列表类型。
dumps:序列化,loads:反序列化
import json dic = {'顾清秋':(175,70,'Music')} ret = json.dumps(dic,ensure_ascii=False) # dump 将字典序列化 print(ret,type(ret)) # {"顾清秋": [175, 70, "Music"]} <class 'str'> res = json.loads(ret) # loads 反序列化 print(res,type(res)) # {'顾清秋': [175, 70, 'Music']} <class 'dict'>
dump 和 load 是直接将对象序列化后写入文件。依赖一个文件句柄。
import json dic = {'顾清秋':(175,70,'Music')} f = open('log',encoding='utf-8',mode='w') # 打开一个文件以‘w’模式 json.dump(dic,f,ensure_ascii=False) # 先接受序列化对象,在接受文件句柄 f.close() f = open('log',encoding='utf-8') # 以'r'模式打开一个文件 content = json.load(f) print(content) # {'顾清秋': [175, 70, 'Music']}
写入多个字典时:
import json dic1 = {'顾清秋':(175,70,'Music')} dic2 = {'顾小白':(175,70,'Music')} dic3 = {'懒笨呆':(175,70,'Music')} f = open('log2',encoding='utf-8',mode='a') # 先序列化,再逐个写入文件 str1 = json.dumps(dic1) f.write(str1+'\n') str2 = json.dumps(dic2) f.write(str2+'\n') str3 = json.dumps(dic3) f.write(str3+'\n') f.close() f = open('log2',encoding='utf-8') # 用for循环读取 for line in f: print(json.loads(line.strip())) # 用loads(反序列化) 打印出原类型 f.close() # {'顾清秋': [175, 70, 'Music']} # {'顾小白': [175, 70, 'Music']} # {'懒笨呆': [175, 70, 'Music']}
dumps 序列化,loads 反序列化:之在内存中操作数据,主要用于网络传输。
dump 序列化,load 反序列化:主要用于一个数据直接存在文件里--直接和文件打交道。
json不支持元组 不支持除了str数据类型之外的key:
import json dic = {(175,70,'Music'):'顾清秋'} # 以元祖为键,json不支持元祖。 ret = json.dumps(dic) print(ret) # TypeError: keys must be a string
pickle模块:可识别元祖。
dumps : 序列化后是一个bytes类型。
loads:反序列化转回原类型。
import pickle dic = {'顾清秋': (175, 70, 'Music')} ret = pickle.dumps(dic) # 序列化结果:不是一个可读的字符串,而是一个bytes类型。 print(ret) res = pickle.loads(ret) print(res) # {'顾清秋': (175, 70, 'Music')}
dump 和 load:
import pickle dic = {'顾清秋': (175, 70, 'Music')} f = open('log2','wb') # 以wb模式就无需编码(不用写encoding='utf-8') pickle.dump(dic,f) # 序列化成bytes类型写入文件 f.close() f = open('log2','rb') # 读取是以rb模式。 content = pickle.load(f) print(content) # {'顾清秋': (175, 70, 'Music')} f.close()
写入多行:
import pickle dic1 = {'顾清秋':(175,70,'Music')} dic2 = {'顾小白':(175,70,'Music')} dic3 = {'懒笨呆':(175,70,'Music')} f = open('log','wb') pickle.dump(dic1,f) pickle.dump(dic2,f) pickle.dump(dic3,f) f.close() f = open('log','rb') while True: try: print(pickle.load(f)) except: break # {'顾清秋': (175, 70, 'Music')} # {'顾小白': (175, 70, 'Music')} # {'懒笨呆': (175, 70, 'Music')}
关于序列化自定义类的对象:
import pickle class A: def __init__(self,name,age): self.name = name self.age = age a = A('顾清秋',17) f = open('顾清秋','wb') pickle.dump(a,f) f.close() f = open('顾清秋','rb') content = pickle.load(f) print(content) # <__main__.A object at 0x000001D0FE619828> print(content.__dict__) # {'name': '顾清秋', 'age': 17} f.close()
模块 shelve:
python 专有的序列化模块,只针对文件。
import shelve f = shelve.open('shelve_file') # 打开文件 f['key'] = {'int': 10,'float':9.5,'strig':'Sample data'} # 直接对文件句柄操作,就可以存入数据。 f.close() f1 = shelve.open('shelve_file') existing = f1['key'] # 取数据的时候也只需要直接用key获取即可,但如果key不存在会报错。 f1.close() print(existing)
设置只读方式:flag = ‘r’
import shelve f = shelve.open('shelve_file',flag = 'r') existing = f['key'] # f['key']['int'] = 50 # 不能修改已有结构中的值 # f['key']['new'] = 'new' # 不能再已有的结构中添加新的项。 f['key'] = 'new' # 但是可以覆盖原来的结构 f.close() print(existing)
写入:writeback = True
import shelve f = shelve.open('shelve_file',writeback = True) f['key'] = {'name':'顾小白','age':17} f['key']['hobby'] = 'Music' f.close() f = shelve.open('shelve_file',flag='r') content1 = f['key'] print(content1) # {'hobby': 'Music', 'name': '顾小白', 'age': 17} f.close()
hashlib——摘要算法:
也是算法的集合,有好多算法。
字符串——> 数字
不同的字符串--->数字一定不同。
无论在哪台机器上,在什么时候计算,对相同的字符串,结果总是一样的。
摘要的过程不可逆。
用法:
1,文件的一致性校验。2,密文验证的时候加密。
密文验证的时候加密:
md5算法:通用的算法。
sha算法:安全系数更高,sha算法有很多种,后面的数字越大,安全系数越高,
得到的数字结果越长,计算的时间越长。
import hashlib m = hashlib.md5() m.update('alex3714'.encode('utf-8')) print(m.hexdigest()) # aee949757a2e698417463d47acac93df # 16进制的数字
为了防止暴力破解和撞库:
加盐:
import hashlib # m = hashlib.md5() m = hashlib.md5('guxiaobai'.encode('utf-8')) m.update('123456'.encode('utf-8')) print(m.hexdigest()) # b25cc83ffee9268a80c0c32e107d1ad5
动态加盐:
import hashlib username = input('>>>') password = input('*>>>') m = hashlib.md5(username.encode('utf-8')) m.update(password.encode('utf-8')) print(m.hexdigest())
文件的一致性校验:
一段字符串直接进行摘要和分成几段摘要的结果是相同的。
import hashlib md5_obj = hashlib.md5() md5_obj.update(b'hello world') print(md5_obj.hexdigest()) # 5eb63bbbe01eeed093cb22bb8f5acdc3 m = hashlib.md5() m.update(b'hello ') m.update(b'world') print(m.hexdigest()) # 5eb63bbbe01eeed093cb22bb8f5acdc3 # 一段字符串直接惊醒摘要和分成几段摘要的结果是相同的。
对文件进行校验,如果两个文件的内容一致,则摘要的结果是一致的。
import hashlib def check(filename): m = hashlib.md5() with open(filename,'rb') as f: content = f.read() m.update(content) return m.hexdigest() print(check('log1')) # 7fc983869a79c4e549268f47bbdc971b print(check('log2')) # 7fc983869a79c4e549268f47bbdc971b print(check('log1') == check('log2')) # True