需求:
XML是早期被广泛使用的数据交换格式
JSON是一种轻量级的数据交换格式,JSON相对于XML而言,更加简单,易读和编写,同时也易于机器解析和生成,除此,我们也可以自定义内部使用的数据交换格式。
将对象转换为可通过网络传输或可以存储到本地磁盘的数据格式(如xml和json等格式的字节串)的过程称为序列化,反之称为反序列化。
对于序列化最普遍的做法就是使用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} |
---|
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] |
---|
python的json模块序列化与反序列化的过程分别叫做:encoding和decoding
json与python间数据类型的对应关系
<th>
JSON
</th>
<td>
Object
</td>
<td>
array
</td>
<td>
string
</td>
<td>
numbers
</td>
<td>
true
</td>
<td>
false
</td>
<td>
null
</td>
<th>
Python
</th>
<td>
dict
</td>
<td>
list
</td>
<td>
str
</td>
<td>
int
</td>
<td>
float
</td>
<td>
True
</td>
<td>
False
</td>
<td>
None
</td>
说明:
示例:
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参数重新指定分隔符,从而去除无用的空白字符;
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} |
---|