定义
- 将对象(变量)从内存中变成可存储或可传输的过程称为序列化,通俗地讲,就是将一个变量 写进文件中保存起来。
- 变量储存在内存中,当程序执行完毕后,该变量就在内存中释放了。
- 将变量内容从序列化的对象中重新读到内存中称为反序列化。
为什么要序列化
- 持久化保持数据状态
- 跨平台(语言)进行数据交互
用法
示例1:普通的文件写入操作,将字典写入文件中,再从字典中取出存为变量
def test1():
"""
将字典写入文件中,这里将字段转成字符串才能写入
"""
dic = {"name": "xiaoming", "age ": "24"}
f = open("test", "w")
#f.write(dic) # 这里如果不将 dic 转化成字符串则无法写入
f.write(str(dic))
f.close()
def test2():
"""
eval函数可以将存入文件的的str 转化为字典
"""
f = open("test", "r")
data = eval(f.read())
print(data, type(data))
f.close()
总结:
1、python中总普通的write 将数据写入文件,如果数据类型为字典事无法写入的,需转化为字符串
2、eval 函数,能将 list 、dict、tuple 转化为str;(str 是将list、dict、tuple转化为str)
示例2:json 序列化
import json
dir = {"name": "xiaoming", "age ": "25"}
def func(name)
"""
这里随便写了个函数,后面会用到
"""
print("in the func")
print("name:",name)
### dumps 序列化与 loads 反序列化
def test_json_dumps():
"""
dumps 函数序列化示例
"""
f = open("json_test", "w")
data = json.dumps(dir)
f.write(data)
f.close()
def test_json_loads():
"""
loads 反序列化示例
"""
f = open("json_test", "r")
data = f.read()
print(type(data)) # 这里可以看出json- dumps 序列化后的变量是字符串
data = json.loads(data)
print(data["name"])
f.close()
### dump 序列化 与load 反序列化
def test_json_dump():
"""
dump 函数序列化示例
"""
f = open("json_test", "w")
json.dump(dir, f)
f.close()
def test_json_load():
"""
load 反序列化示例
"""
f = open("json_test", "r")
# data1 = f.read()
# print(data1, type(data1))
data = json.load(f)
print(data["name"], type(data))
f.close()
### json 的 dumps(dumps) 与load(load)实现不了的
dir_func = {
"name": "xiaom",
"age":"24",
"func":func
}
#这个字典里面存了一个方法 的地址
def test_json_dumps():
f = open("json_test", "w")
data = json.dumps(dir_func )
f.write(data)
f.close()
### 执行test_json_dumps()发现报错了:Object of type 'function' is not JSON serializable,
### 说明 json 序列化并不能解决一些特殊场景:无法序列化对象是 function 的场景。
总结:
1、json 序列化有 dumps(loads)、dump(load)两个方法,都是 序列化成 str在文件中存储,两个放必须一组一组用,不然可能出现错误
2、对于 dumps(loads)、dump(load)的区别,dump(load)跟dumps(loads)差不多,dump(load)与文件操作结合起来使用,大多数场景下都是dumps(loads)
3、Json可以在不同语言之间使用
4、json 序列化 无法将 对象是含 function的 对象序列化,如果需解决这一问题,需用到 python 的pickle 模块
示例3: pickle序列化
- pickle 模块基本上功能使用和JSON模块没有太大区别;
- pickle 不是用于多种语言间的数据传输,它仅作为python对象的持久化或python程序间进行互相传输对象的方法;
import pickle
def func(name):
"""
这里随便写了个函数,后面会用到
"""
print("in the func")
print("name:",name)
dir_func = {
"name": "xiaom",
"age":"24",
"func":func
}
def test_pickle_dumps():
"""
"""
f = open("pickle_test", "wb") #由于pickle 序列化对象为二进制,所以要有wb\rb 打开文件
data = pickle.dumps(dir_func )
f.write(data) # 查看序列化后的pickle_test文件内容,与json 不同,是python pickle特有的一种格式,这决定 pickle序列化只能python 程序间使用。
f.close()
def test_pickle_loads():
"""
loads 反序列化示例
"""
f = open("pickle_test", "rb")
data = f.read()
print(type(data)) #这里可以看出pickle- dumps 序列化后的变量是二进制(bytes)
data = pickle.loads(data)
print(data["func"](xiaoming), type(data)) #这里如果再重写 一个func函数(函数名一定要与序列化的函数名相同,执行的是重写的函数)
print(data["name"])
f.close()
总结:
1、pickle序列化存储的数据格式是二进制
2、pickle序列化只能在python 程序间使用
3、pickle反序列化时,如果对象中含function,而恰好当前程序也有相同函数名的function,则会执行当前程序的同名function
示例4: MessagePack 模块 序列化
- MessagePack是一个基于二进制高效的对象序列化类库,可以用于跨语言通讯;
- 它可以像JSON一样,在多种语言之间交互结构对象;但是它比JSON更快也更轻巧;兼容json和pickle;
- 用法与 json、pickle 一样
dicr ={
"default": {"a": "test"},
"mysql": {
"default-character-set": "utf-8",
"a": 1000
},
"mysqlid": {
"datadir": "/dbserver/data",
"prot": "3306",
"character-set-server": "utf-8",
"sql_mode": "NO_ENGINE_SUBSTIUTING,..."
}
}
def msg_test1():
msgpack.dump(dicr, open("msg_test.json", "wb"))
open("msg_test.json", "wb").close()
def msg_test2():
data = msgpack.load(open("msg_test.json", "rb"))
print(data,type(data))
open("msg_test.json", "wb").close()