Python数据序列化和反序列化

前言

  • 现实需求
    每种编程语言都有自己的数据类型,其中面向对象的编成语言还允许开发者自定义数据类型(i.e. 自定义类),Python也是一样。很多时候我们会有这样的需求:
    • 把内存中的各种数据类型的数据通过网络传送给其它机器或客户端
    • 把内存中的各种数据类型的数据保存到本地磁盘持久化
  • 数据格式
    如果要将一个系统内的数据通过网络传输给其它系统或者客户端,我们通常都需要先把这些数据转化为字符或字符串,而且需要规定一种统一的数据格式才能让数据接收端正确解析并理解这些数据的含义。XML是早期被广泛使用的数据交换格式,在早期的系统集成论文中经常可以看到它的身影; 如今大家使用更多的数据交换格式是JSON(JavaScript Object Notation), 它是一种轻量级的数据交换格式。JSON相对于XML而言,更加轻便、易于理解和编写,同时也易于机器解析和生成。除此之外,我们也可以自定义内部使用的数据交换格式。
    如果是想把数据持久化到本地磁盘,这部分数据通常只是供系统内部使用,因此数据转换协议以及转换后的数据格式也就不要求是标准、统一的,只要本系统内部能够正确识别即可。但是,系统内部的转换协议通常会随着编程语言版本的升级而发生变化(改进算法、提高效率),因此通常会涉及转换协议与编程语言的版本兼容问题,下面要介绍的pickle协议就是这样一个例子
  • 序列化和反序列化
    将对象转换为可通过网络传输或可以存储到本地磁盘的数据格式(如XML, JSON或特定格式的字符串) 的过程称之为序列化; 反之,则称为反序列化。

相关Module

模块名称 描述 提供的API
json 用于实现Python数据类型与通用(json)字符串之间的转换 dumps(); dump(); loads(); load()
pickle 用于实现Python数据类型与Python特定二进制格式之间的转换 dumps(); dump(); loads(); load()
shelve 专门用于将Python数据类型的数据持久化到磁盘,shelve是一个类似于dict的对象 open()

json模块

json与pickle相比具有更好的可读性(pickle是二进制数据)和跨平台性。
json模块提供了以下两个方法来进行序列化和反序列化操作:

# 序列化:将Python对象转换成json字符串
dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)

# 反序列化:将json字符串转换成Python对象
loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

除此之外,json模块还提供了两个额外的方法允许我们直接将序列化后得到的json数据保存到文件中,以及直接读取文件中的json数据进行反序列化操作:

# 序列化:将Python对象转换成json字符串并存储到文件中
dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)

# 反序列化:读取指定文件中的json字符串并转换成Python对象
load(fp, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
  • 序列化为字符串
dict = {'age': '23, 'job': 'student'}
dict_str = json.dumps(dic)
print(type(dic_str), dict_str)
# out: <class 'str'> {"age": 23, "job": "student"}

dict_obj = json.loads(dic_dir)
print(type(dict_obj), dict_obj)
# out: <class 'dict'> {'age': 23, 'job': 'student'}

可以看到,dumps()函数将对象转换成了字符串。loads()函数又将其恢复成字典。

  • 存储为json文件

也可以存储在json文件中

dict = {'age': 23, 'job': 'student'}
with open('abc.json', 'w', encoding='utd-8') as f:
	json.dump(dict, f)
with open('abc.json', encoding='utf-8') as f:
	obj = json.load(f)
	print(obj)
  • 存储为自定义对象
    还是上面的

pickle模块

  • 存储在变量中
    dumps(obj) 返回存入的字节
dict = {'age': 23, ‘job’= 'student'}
byte_data = pickle.dumps(dic)
print(byte_data)

# out -> b'\x80\x03}q\x00(X\x03\x00\x00\...'
  • 读取数据
    数据以字节保存在了byte_data变量中,需要再次使用的时候使用loads()函数就可以了
obj = pickle.loads(byte_data)
print(obj)
  • 存储在文件中
    也可以存在文件中,使得对象持久化。使用的是dumpload函数。由于pickle写入的是二进制数据,所以打开方式需要以wbrb模式。
# 序列化
with open('abc.pkl', 'wb') as f:
	dict = {'age': 23, 'job': 'student'}
	pickle.dump(dic, f)

# 反序列化
with open('abc.pkl', 'rb') as f:
	aa = pickle.load(f)
	print(aa)
	print(type(aa))  # <class 'dict'>
  • 序列化用户自定义的对象
    加入我写了个类

Reference:
https://www.cnblogs.com/yyds/p/6563608.html
https://www.cnblogs.com/sun-haiyu/p/7087088.html
https://www.cnblogs.com/wxzhe/p/8949331.html
https://www.cnblogs.com/lingluo/p/6075309.html

猜你喜欢

转载自blog.csdn.net/weixin_42018112/article/details/88926115