常用模块2
Posted tornadoes-destroy-parking-lots
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常用模块2相关的知识,希望对你有一定的参考价值。
序列化与反序列化
什么是序列化
- 序列化指的是把内存的数据类型转换成一个特定的格式的内容
- 序列化成的格式:json / pickle
- 原本我们学过序列化和反序列化的土办法:str() 与eval()
为何要序列化
序列化得到的特定格式有两种用途
- 用于存储:可以存档
- 传输给其他平台使用:跨平台数据交互,当一款软件的不同组建使用不同的编程语言编写的时候,不同语言的数据类型不兼容,如python中的列表与java中的数组
重点:
- 对用途1中的格式,可以是一种专用的格式:pickle只有python可以识别
- 对于用途2中的特定格式,应该是一种通用,能够被所有语言识别的格式:json
- json不能支持python所有的数据类型,json只是包含所有数据类型共有的类型:如集合就不在json中被支持
json
序列化:json.dumps import json res = json.dumps([1,‘a‘,True]) print(res,type(res)) 反序列化:json.loads l = json.loads(res) print(res)
读写文件序列化的简单方法
序列化写入文件的简单方法:json.dump(str,f) with open(‘text.json‘,mode=‘rt‘,encoding=‘utf-8‘) as f: json.dump([1,‘aaa‘,True,False],f) # 不用一行行字符串dumps再写,dump帮你写进去了 反序列化的简单方法 json.load(json,f) with open(‘test.json‘,mode=‘rt‘,encoding=‘utf-8‘) as f: l=json.load(f) print(l,type(l)) # 不用一行行读了再反序列化,直接帮你读了 # 相当于 with open(‘test.json‘,mode=‘rt‘,encoding=‘utf-8‘) as f: json_res=f.read() l=json.loads(json_res) print(l,type(l))
强调
-
json没有单引号,只用双引号
-
一定要搞清楚json格式,不要跟python混淆
-
在python2中,str就是bytes类型,python3.6以后,对于json格式前面加b,可以反解出正常的类型,只有3.5不行
3.6可以用rb模式打开json格式文件,3.5只能用rt
猴子补丁
应用场景:想把原来的方法换成更好的办法,但是不想改变原本的使用模块的方法,也不想在程序的每一个文件里导入新的模块
把程序中的某种功能换掉,应该在入口文件打补丁,把要换掉的功能用新功能覆盖
import json import ujson def monkey_path_json(): json.__name__=‘ujson‘ json.dumps = ujson.dumps json.loads = ujson.loads # 把json的两个方法换成了ujson的两个方法,使用的时候名字不改变,在改变功能的时候名称空间不会改变,所以原来写的代码中json方法还是指向原来的 # 如果import ujson as json,因为产生了新的名称空间,后面调用的时候不会用ujson的名称空间
pickle
用法与json一样
XML
以前用的跨平台交互格式,用到就是xml,新的软件用的都是json
configparser
用于写配置文件,存放配置项
直接在目录里(db)建立文件,settings.ini,在db_handler里导入configparser就可以了
configparser专门用来解析如下的文件
[section1]
x=1
y=2
import configparser config = configparser.ConfigParser() # 这步得到一个对象,供我们操作 confi.read(‘test.ini‘) # 获取所有的section,返回一个section名字的列表 print(config.sections()) # 获取某一section下所有的option的key print(config.options(‘section1‘))
# 获取某一个section下的所有key和value,返回小元组 print(config.items(‘section1‘))
# 获取一个section下的一个value,得到的是字符串格式 print(config.get(‘section1‘,‘user‘))
# 将读取的配置按指定类型输出 val1=config.getint(‘section1‘,‘age‘) # int格式 val2=config.getboolean(‘section1‘,‘is_admin‘) # 布尔值格式
hashlib 模块
hash一类算法接收传入的内容,经过运算得到一串hash值
hash值的特点
-
只要每次传入的值一样,得到的结果一定一样
-
如果固定一个hash算法,比如md5,无论传的内容有多大,其内容不会改变
-
不能根据hash值反推到原内容:用于密码加密
用户注册的时候不再传明文了,传hash值,登陆的时候也比较hash值
hash的用途
- 用于密码密文传输与验证
- 用于校验文件完整性,无论文件多大,得到的哈希值是固定的
import hashlib #使用方法 # 使用md5,使用别的方法也是得到哈希值,复杂度不同,得到的长度不一样 m = hashib.md5(‘hello‘.encode(‘utf-8‘)) # m相当于一个哈希工厂,用update往里面送原料,最终得到的结果是所有传入的值拼接起来哈希的结果 m.update(‘hello‘.encode(‘utf-8‘)) m.update(‘world‘.encode(‘utf-8‘)) res = m.hexdigest() # 拿到 ‘hellohelloworld‘ 的哈希值
#校验的时候,推荐使用for循环一行行m.update(line)方法,缺点是行数多的时候会比较慢
#防止别人猜到,改进方法
# 随机地取某一段进行校验
f = open(‘a.txt‘,‘rb‘)
f.seek(随机数) # 随机选几个位置
info = f.read(2000) # 一次读2000个字节
m1.update(info)
模拟撞库
import hashlib
passwords = [‘111‘,‘222‘,‘ssss‘]
dic = {}
# 制作密码字典
for p in passwords:
res = hashlib.md5(p.encode(‘utf-8‘))
dic[p] = res.hexdigest()
# 撞库
for k,v in dic.items():
if v == cryptograph:
print(‘撞库成功,名文密码是 %s‘ %k)
break
密码加严
import hashlib
m = hashlib.md5()
m.update(‘nb‘.encode(‘utf-8‘))
m.update(‘deimos‘.encode(‘utf-8‘))
m.update(‘nb‘.encode(‘utf-8‘))
print(m.hexdigest)
# 拿到密码之后先对明文进行处理,对某些位置拆开,加入干扰的字符
subprocess
用于执行系统命令的模块,得到的结果都是bytes类型,不会乱码
import subprocess
subprocess.Popen()
以上是关于常用模块2的主要内容,如果未能解决你的问题,请参考以下文章