0x00 简介
什么叫序列化:将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化。字符串是有顺序的,普遍所说的序列化都是转向一个字符串的过程。
在写文件(数据存储)、网络上传输(只能传bytes)时只能对字符串进行操作,所以基于这些情况必须把“字典”等转为字符串才行。
序列化的目的:
1、以某种存储形式使自定义对象持久化
2、将对象从一个地方传递到另一个地方。
3、使程序更具维护性。
# 从数据类型 –> 字符串的过程 序列化
# 从字符串 –> 数据类型的过程 反序列化
几个重要的模块:json、pickle、shelve ,其中json和pickle专门处理json格式
0x01 json模块
json 模块提供了四个方法: dumps、dump、loads、load
python的基本数据类型:数字int,布尔值bool,字符串str,列表list,元组tuple,字典dict
(1)dumps和dump 序列化方法
dumps:将python的基本数据类型序列化为字符串
dump :将python的基本数据类型序列化成字符串并写入文件中
>>> import json >>> json.dumps([])#dumps可以格式化所有的基本数据类型为字符串 '[]' >>> list = ['1','2','3']#列表中元素双引号包裹也是下面结果输出 >>> json.dumps(list)#列表 '["1", "2", "3"]' >>> json.dumps(1)#数字 '1' >>> json.dumps('1')#字符串 '"1"' >>> dict = {"name":"purplet","age":23} >>> json.dumps(dict)#字典 '{"name": "purplet", "age": 23}' >>> tup = (1, 2, 3, 4, 5 )#元组 >>> json.dumps(tup) '[1, 2, 3, 4, 5]'
从上面的转换中也可以看出输出的结果全都是字符串类型
import json a = {"name":"purplet", "age":20} with open("test.json", "w", encoding='utf-8') as f: # indent 超级好用,格式化保存字典,默认为None,不进行格式化,当indent小于等于0时格式化为零个空格 f.write(json.dumps(a),indent=4) # json.dump(a,f,indent=4) # 和上面的效果一样
输出:
{
"name": "purplet",
"age": 20
}
当写入的字典格式文件中存在中文时,如果不加上ensure_ascii=False,默认会将其转换为unicode编码
import json
a = {"name":"张三", "age":18}
with open("test.json", "w", encoding='utf-8') as f:
# indent 超级好用,格式化保存字典,默认为None,不进行格式化,当indent小于等于0时格式化为零个空格
f.write(json.dumps(a,ensure_ascii=False,indent=4))
# json.dump(a,f,indent=4) # 和上面的效果一样
(2)loads 和 load反序列化方法
loads 反序列化:将字符串反序列化成python的基本数据类型
load 反序列化:读取文件字符串,反序列化成python的基本数据类型
import json
#字典
dict_str = '{"k1":"v1","k2":"v2"}'
dict_json = json.loads(dict_str)
print(dict_json)
print(type(dict_json))
#整形
number_str = '1'
number_json = json.loads(number_str)
print(number_json)
print(type(number_json))
#列表
list_str = '[1,2,3]'
list_jaon = json.loads(list_str)
print(list_jaon)
print(type(list_jaon))
#元组
#元组与列表一致
输出:
{'k1': 'v1', 'k2': 'v2'}
<class 'dict'>
1
<class 'int'>
[1, 2, 3]
<class 'list'>
从上面的转换中也可以看出输出的结果全都是python数据类型
import json f = open('test.json','r',encoding='utf-8')#内容包含中文需编码utf-8 res = json.load(f) print(res)
输出:{‘name’: ‘张三’, ‘age’: 18}
json强调:json格式没有单引号,只有双引号
0x02 pickle模块
该模块同样具备load loads dump dumps四个方法
import pickle
dic = {'name': 'purplet', 'age': 20, 'sex': 'male'}
print(type(dic)) # <class 'dict'>
j = pickle.dumps(dic)
print(type(j)) # <class 'bytes'>
f = open('序列化对象_pickle', 'wb') # 注意是w是写入str,wb是写入bytes,j是'bytes'
f.write(j) # -------------------等价于pickle.dump(dic,f)
f.close()
# -------------------------反序列化
import pickle
f = open('序列化对象_pickle', 'rb')
data = pickle.loads(f.read()) # 等价于data=pickle.load(f)
print(data['age'])#20
同时文件的读写都是byte类型,而且对于pickle来讲可以分次序列化/反序列化(json这样就会报错)。
import pickle
import time
struct_time1 = time.localtime(100000000)
struct_time2 = time.localtime(200000000)
f = open('pickle_text','wb')
pickle.dump(struct_time1,f)#同json模块一样不加s的对文件操作
pickle.dump(struct_time2,f)
f.close()
#文件中内容
# �ctime
# struct_time
# q (M�KKKK.K(KK>K tq}q(X tm_zoneqX ?D1¨²¡À¨º¡Á?¨º¡À??qX tm_gmtoffqM�pu�qRq.�ctime
# struct_time
# q (M�KKKK!KKK}K tq}q(X tm_zoneqX ?D1¨²¡À¨º¡Á?¨º¡À??qX tm_gmtoffqM�pu�qRq.
f = open('pickle_text','rb')
struct_time1 = pickle.load(f)
struct_time2 = pickle.load(f)
print(struct_time1)
print(struct_time2)

文章参考Root师傅的博客:https://shawroot.cc/archives/901