序列化模块
序列化:是指将原本的字典,列表的内容转换成一个字符串的过程
序列化的过程:把其他数据类型转化成字符串,bytes的过程
序列化的目的:
1.以某种储存形式使自定义对象持久化 2.将对象从一个地方传递到另一个地方 3.使程序更具维护性
json
json模块包含四个功能:dumps,loads,dump,load
json在所有的语言之间都通用,及json序列化的数据在python上序列化了那么在Java等语言中也可反序列化,但是json也有局限,就是它能处理的数据类型非常有限,
必须是字符串,列表,字典和数字,且字典中的key值只能是字符串
序列化与反序列化
dumps 与 loads
dic = {'key': 'value', 'key2': 'value2'} ret = json.dumps(dic) # 序列化 print(dic, type(dic)) print(ret, type(ret)) 运行结果: {'key': 'value', 'key2': 'value2'} <class 'dict'> {"key": "value", "key2": "value2"} <class 'str'> #注意,json转换完的字符串类型的字典中的字符串是由""表示的 res = json.loads(ret) # 反序列化 print(res, type(res)) 运行结果: {'key': 'value', 'key2': 'value2'} <class 'dict'> #注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
dumps与loads存在的问题
问题一:序列化再反序列化后会将字典中的int变为str
dic = {1: 'value', 2: 'value2'} ret = json.dumps(dic) # 序列化 print(dic, type(dic)) print(ret, type(ret)) res = json.loads(ret) # 反序列化 print(res, type(res)) 运行结果: {1: 'value', 2: 'value2'} <class 'dict'> {"1": "value", "2": "value2"} <class 'str'> {'1': 'value', '2': 'value2'} <class 'dict'>
问题二:序列化再反序列化后会将字典中的元组变为列表
dic = {1: [1, 2, 3], 2: (4, 5, 'aa')} ret = json.dumps(dic) # 序列化 print(dic, type(dic)) print(ret, type(ret)) res = json.loads(ret) # 反序列化 print(res, type(res)) 运行结果: {1: [1, 2, 3], 2: (4, 5, 'aa')} <class 'dict'> {"1": [1, 2, 3], "2": [4, 5, "aa"]} <class 'str'> {'1': [1, 2, 3], '2': [4, 5, 'aa']} <class 'dict'>
问题三:不可以序列化集合
s = {1, 2, 'aaa'} json.dumps(s)
问题四:序列化的字典中不可用str以外的类型作为字典的key
json.dumps({(1, 2, 3): 123})
TypeError: keys must be a string
dump 与 load 用来直接与文件进行操作
dic = {'key1': 'value1', 'key2': 'value2'} with open('json_file', 'a') as f: json.dump(dic, f) with open('json_file', 'r') as f: dic = json.load(f) print(dic.keys()) 运行结果: dict_keys(['key1', 'key2']) # 需注意的是可以多次dump,但是多次dump后的load会报错
那么如果连续的存取操作就需要如下处理:
dic = {'key1': 'value1', 'key2': 'value2'} with open('json_file', 'a') as f: str_dic = json.dumps(dic) f.write(str_dic+'\n') str_dic = json.dumps(dic) f.write(str_dic + '\n') str_dic = json.dumps(dic) f.write(str_dic + '\n') with open('json_file', 'r') as f: for line in f: dic = json.loads(line.strip()) print(dic.keys()) 运行结果: dict_keys(['key1', 'key2']) dict_keys(['key1', 'key2']) dict_keys(['key1', 'key2'])
pickle
pickle进行的序列化支持python的几乎所有的数据类型
pickle模块同样包含四个功能:dumps,loads,dump,load
dic = {(1, 2, 3): {'a', 'b'}, 1: 'abc'} ret = pickle.dumps(dic) print(ret) 运行结果: b'\x80\x03}q\x00(K\x01K\x02K\x03\x87q\x01cbuiltins\nset\nq\x02]q\x03(X\x01\x00\x00\x00bq\x04X\x01\x00\x00\x00aq\x05e\x85q\x06Rq\x07K\x01X\x03\x00\x00\x00abcq\x08u.' # pickle.dumps的结果只能是字节
与json不同pickle.dump和pickle.load可以进行多次
dic = {(1, 2, 3): {'a', 'b'}, 1: 'abc'} dic1 = {(1, 2, 3): {'a', 'b'}, 2: 'abc'} dic2 = {(1, 2, 3): {'a', 'b'}, 3: 'abc'} dic3 = {(1, 2, 3): {'a', 'b'}, 4: 'abc'} with open('pickle_file', 'wb') as f: pickle.dump(dic, f) pickle.dump(dic1, f) pickle.dump(dic2, f) pickle.dump(dic3, f) with open('pickle_file', 'rb') as f: ret = pickle.load(f) print(ret, type(ret)) ret = pickle.load(f) print(ret, type(ret)) ret = pickle.load(f) print(ret, type(ret)) ret = pickle.load(f) print(ret, type(ret)) 运行结果: {(1, 2, 3): {'a', 'b'}, 1: 'abc'} <class 'dict'> {(1, 2, 3): {'a', 'b'}, 2: 'abc'} <class 'dict'> {(1, 2, 3): {'a', 'b'}, 3: 'abc'} <class 'dict'> {(1, 2, 3): {'a', 'b'}, 4: 'abc'} <class 'dict'>
当load的次数超过dump时会进行范围的报错,可以用try--except解决:
with open('pickle_file', 'rb') as f: while True: try: ret = pickle.load(f) print(ret, type(ret)) except EOFError: break