前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python基础—序列化操作

python基础—序列化操作

作者头像
dogfei
发布2020-07-31 14:33:45
5260
发布2020-07-31 14:33:45
举报
文章被收录于专栏:devops探索devops探索

序列化python对象

需求:

  • 把内存中的各种数据类型的数据通过网络传送给其他机器或客户端
  • 把内存中的各种数据类型的数据保存到本地磁盘持久化
  • 如果要将系统内的数据通过网络传输给其他系统或客户端,我们通常需要把这些数据转化为字符串或字节串,且需要规定统一的数据格式才能让数据接收端正确解析并理解这些数据的含义

XML是早期被广泛使用的数据交换格式

JSON是一种轻量级的数据交换格式,JSON相对于XML而言,更加简单,易读和编写,同时也易于机器解析和生成,除此,我们也可以自定义内部使用的数据交换格式。

什么是序列化和反序列化

将对象转换为可通过网络传输或可以存储到本地磁盘的数据格式(如xml和json等格式的字节串)的过程称为序列化,反之称为反序列化。

pickle模块

对于序列化最普遍的做法就是使用pickle模块,pickle模块用于实现python数据类型与python特定二进制格式之间的转换,方法有:dump(),dumps(),load(),loads()

序列化:pickling,将python对象转换为字节流的过程

反序列化:unpickling,将字节流二进制文件或字节对象转换回python对象的过程

例1:

1 2 3 4 5 6 7 8 9 10 11 12 13

>>> import pickle >>> f = open('/devilf/data/6.txt','wb') >>> pickle.dump([1,2,3,4,5],f) >>> pickle.dump('hello',f) >>> pickle.dump({'Apple','Pear','Banana'},f) >>> f.close() >>> f = open('/devilf/data/6.txt','rb') >>> pickle.load(f) [1, 2, 3, 4, 5] >>> pickle.load(f) 'hello' >>> pickle.load(f) {'Pear', 'Apple', 'Banana'}

例2:

1 2 3 4 5 6 7 8 9

序列化: >>> pickle_data = {'a': 'str','c': True,'e': 10,'b': 11.1,'d': None,'f': [1,2,3],'g': (4,5,6)} >>> pickle_a = pickle.dumps(pickle_data) >>> pickle_a b'\x80\x03}q\x00(X\x01\x00\x00\x00bq\x01G@&333333X\x01\x00\x00\x00gq\x02K\x04K\x05K\x06\x87q\x03X\x01\x00\x00\x00fq\x04]q\x05(K\x01K\x02K\x03eX\x01\x00\x00\x00aq\x06X\x03\x00\x00\x00strq\x07X\x01\x00\x00\x00dq\x08NX\x01\x00\x00\x00eq\tK\nX\x01\x00\x00\x00cq\n\x88u.' 反序列化: >>> pickle_b = pickle.loads(pickle_a) >>> pickle_b {'b': 11.1, 'g': (4, 5, 6), 'c': True, 'f': [1, 2, 3], 'a': 'str', 'e': 10, 'd': None}

dump()和load()用法

1 2 3 4 5 6 7 8 9 10 11

>>> pickle_data = {'a': 'str','c': True,'e': 10,'b': 11.1,'d': None,'f': [1,2,3],'g': (4,5,6)} 持久化到文件: >>> with open('/devilf/data/pickle.txt','wb') as f: ... pickle.dump(pickle_data,f) ... 从文件中读取数据 >>> with open('/devilf/data/pickle.txt','rb') as f: ... pickle_c = pickle.load(f) ... print(pickle_c) ... {'b': 11.1, 'g': (4, 5, 6), 'c': True, 'f': [1, 2, 3], 'a': 'str', 'e': 10, 'd': None}

自定义数据类型的序列化/反序列化

1 2 3 4 5 6 7 8

class Student(object): def __init__(self, name, age, sno): self.name = name self.age = age self.sno = sno def __repr__(self): return 'Student [name: %s, age: %d, sno: %d]' % (self.name, self.age, self.sno)

pickle模块可以直接对自定数据类型进行序列化/反序列化操作,无需编写额外的处理函数或类。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

>>> stu = Student('Tom', 19, 1) >>> print(stu) Student [name: Tom, age: 19, sno: 1] # 序列化 >>> var_b = pickle.dumps(stu) >>> var_b b'\x80\x03c__main__\nStudent\nq\x00)\x81q\x01}q\x02(X\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Tomq\x04X\x03\x00\x00\x00ageq\x05K\x13X\x03\x00\x00\x00snoq\x06K\x01ub.' # 反序列化 >>> var_c = pickle.loads(var_b) >>> var_c Student [name: Tom, age: 19, sno: 1] # 持久化到文件 >>> with open('pickle.txt', 'wb') as f: ... pickle.dump(stu, f) ... # 从文件总读取数据 >>> with open('pickle.txt', 'rb') as f: ... pickle.load(f) ... Student [name: Tom, age: 19, sno: 1]

json模块

python的json模块序列化与反序列化的过程分别叫做:encoding和decoding

  • encoding:把python对象转换成json字符串
  • decoding:把json字符串转换成python对象

json与python间数据类型的对应关系

Python转JSON
代码语言:javascript
复制
<th>
  JSON
</th>
代码语言:javascript
复制
<td>
  Object
</td>
代码语言:javascript
复制
<td>
  array
</td>
代码语言:javascript
复制
<td>
  string
</td>
代码语言:javascript
复制
<td>
  numbers
</td>
代码语言:javascript
复制
<td>
  true
</td>
代码语言:javascript
复制
<td>
  false
</td>
代码语言:javascript
复制
<td>
  null
</td>
JSON转Python
代码语言:javascript
复制
<th>
  Python
</th>
代码语言:javascript
复制
<td>
  dict
</td>
代码语言:javascript
复制
<td>
  list
</td>
代码语言:javascript
复制
<td>
  str
</td>
代码语言:javascript
复制
<td>
  int
</td>
代码语言:javascript
复制
<td>
  float
</td>
代码语言:javascript
复制
<td>
  True
</td>
代码语言:javascript
复制
<td>
  False
</td>
代码语言:javascript
复制
<td>
  None
</td>

说明:

  • Python dict中的非字符串key被转换成JSON字符串时都会被转换为小写字符串;
  • Python中的tuple,在序列化时会被转换为array,但是反序列化时,array会被转化为list;
  • 由以上两点可知,当Python对象中包含tuple数据或者包含dict,且dict中存在非字符串的key时,反序列化后得到的结果与原来的Python对象是不一致的;
  • 对于Python内置的数据类型(如:str, unicode, int, float, bool, None, list, tuple, dict)json模块可以直接进行序列化/反序列化处理;对于自定义类的对象进行序列化和反序列化时,需要我们自己定义一个方法来完成定义object和dict之间进行转化。

示例:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

序列化: >>> json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}) '{"b": 11.1, "g": [4, 5, 6], "f": [1, 2, 3], "a": "str", "d": null, "e": 10, "c": true}' 序列化并对key进行排序: >>> json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5,6)},<span style="color: #ff6600;">sort_keys=True</span>) '{"a": "str", "b": 11.1, "c": true, "d": null, "e": 10, "f": [1, 2, 3], "g": [4, 5, 6]}' sort_keys=True,表示序列化时对dict的key进行排序 序列化并对key进行排序并格式化输出: >>> print(json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)},sort_keys=True,<span style="color: #ff6600;">indent=4</span>)) { "a": "str", "b": 11.1, "c": true, "d": null, "e": 10, "f": [ 1, 2, 3 ], "g": [ 4, 5, 6 ] } indent参数:表示缩进,它可以使得数据存储的格式变得更加优雅、可读性更强;如果indent是一个非负整数或字符串,则JSON array元素和object成员将会被以相应的缩进级别进行打印输出;如果indent是0或负数或空字符串,则将只会插入换行,不会有缩进。

**separators参数_:_** 尽管indent参数可以使得数据存储的格式变得更加优雅、可读性更强,但是那是通过添加一些冗余的空白字符进行填充的。当json被用于网络数据通信时,应该尽可能的减少无用的数据传输,这样可以节省带宽并加快数据传输速度。json模块序列化Python对象后得到的json字符串中的’,’号和’:’号分隔符后默认都会附加一个空白字符,我们可以通过separators参数重新指定分隔符,从而去除无用的空白字符;

  • 该参数的值应该是一个tuple(item_separator, key_separator)
  • 如果indent是None,其默认值为(‘, ‘, ‘: ‘)
  • 如果indent不为None,则默认值为(‘,’, ‘: ‘)
  • 我们可以通过为separator赋值为(‘,’, ‘:’)来消除空白字符

1 2 3 4

>>> json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}) '{"b": 11.1, "g": [4, 5, 6], "f": [1, 2, 3], "a": "str", "d": null, "e": 10, "c": true}' >>> json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)},separators=(',',':')) '{"b":11.1,"g":[4,5,6],"f":[1,2,3],"a":"str","d":null,"e":10,"c":true}'

反序列化:

1 2 3 4

>>> json.loads('{"a": "str", "c": true, "b": 11.1, "e": 10, "d": null, "g": [4, 5, 6], "f": [1, 2, 3]}') {'b': 11.1, 'g': [4, 5, 6], 'f': [1, 2, 3], 'a': 'str', 'd': None, 'e': 10, 'c': True} >>> json.loads('{"a":"str","c":true,"b":11.1,"e":10,"d":null,"g":[4,5,6],"f":[1,2,3]}') {'b': 11.1, 'g': [4, 5, 6], 'f': [1, 2, 3], 'a': 'str', 'd': None, 'e': 10, 'c': True}

dump()与load()函数示例

1 2 3 4 5 6 7 8 9

序列化到文件中: >>> with open('/devilf/data/test.json','w') as f: ... json.dump({'a':'str中国', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)},f,indent=4) ... 反序列化文件中的内容: >>> with open('/devilf/data/test.json','r') as f: ... json.load(f) ... {'b': 11.1, 'g': [4, 5, 6], 'c': True, 'f': [1, 2, 3], 'a': 'str中国', 'e': 10, 'd': None}

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-02-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 序列化python对象
    • 什么是序列化和反序列化
      • pickle模块
      • json模块
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档