序列化模块

序列化:是指将原本的字典,列表的内容转换成一个字符串的过程

序列化的过程:把其他数据类型转化成字符串,bytes的过程

序列化的目的:

1.以某种储存形式使自定义对象持久化
2.将对象从一个地方传递到另一个地方
3.使程序更具维护性

B(8XC6YU6KK]CL{K4EEP03K

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

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会报错
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'])
连续的dump与load处理

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'>
pickle

当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

 

posted @ 2018-08-21 17:44  YaoSir66  阅读(118)  评论(0编辑  收藏  举报