python 序列化与反序列化

定义

  • 将对象(变量)从内存中变成可存储或可传输的过程称为序列化,通俗地讲,就是将一个变量 写进文件中保存起来。
  • 变量储存在内存中,当程序执行完毕后,该变量就在内存中释放了。
  • 将变量内容从序列化的对象中重新读到内存中称为反序列化。

为什么要序列化

  • 持久化保持数据状态
  • 跨平台(语言)进行数据交互

用法

示例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()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值