27 序列化模块

序列化的意思其实就是:

得到一个字符串的结果 过程就叫序列化


字典 / 列表 / 数字 /对象 -序列化->字符串


为什么要序列化?
1.要把内容写入文件    序列化
2.网络传输数据   序列化


序列化方法:
1.str()强转


2、json

  能处理的数据类型 : 有限,限制比较多
  能使用的语言 : 所有语言
  方法 : dump/load dumps/loads

   json.dumps() 序列化
  json.loads() 反序列化
import json

dic = {'aaa': 'bbb', 'ccc': 'ddd'}
str_dic = json.dumps(dic)
print(dic)     # {'aaa': 'bbb', 'ccc': 'ddd'}
print(str_dic, type(str_dic))    # {"aaa": "bbb", "ccc": "ddd"} <class 'str'>    都是双引号
with open('json_dum p', 'w') as f:
    f.write(str_dic)
ret = json.loads(str_dic)   # {'aaa': 'bbb', 'ccc': 'ddd'} <class 'dict'>
print(ret, type(ret))
print(ret['aaa'])   # bbb

写到文件里:json.dump(dic,f)

dic = {'aaa':'bbb','ccc':'ddd'}
with open('json_dump2', 'w') as f:
    json.dump(dic,f)
# 从文件中拿出来,直接是str
with open('json_dump2') as f:
    print(type(json.load(f)))

JSON的限制

    1:

      如果是数字为key,那么dump之后会强行转成字符串数据类型

dic = {1:2,3:4}
str_dic = json.dumps(dic)
print(str_dic)
new_dic = json.loads(str_dic)
print(new_dic)

-----------------------
{"1": 2, "3": 4}
{'1': 2, '3': 4}

教训是key 不能是数字啊!  变完后,恢复不了了呀

元组:

     json是否支持元组,对元组做value的字典会把元组强制转换成列表

dic = {'abc':(1,2,3)}
str_dic = json.dumps(dic)
print(str_dic)
new_dic = json.loads(str_dic)
print(new_dic)

-------------------
{"abc": [1, 2, 3]}
{'abc': [1, 2, 3]}

  

json不支持元组做key
dic = {(1,2,3):'abc'}
str_dic = json.dumps(dic)  # 报错

对列表的dump
lst = ['aaa',123,'bbb',12.456]
with open('json_demo','w') as f:
    json.dump(lst,f)

# ---- 这边偷偷把字符串双引号改成单引号----
with open('json_demo') as f:
    ret = json.load(f)
    print(ret)  # load 回来就会报错
能不能多次dump数据到文件里  
        可以多次dump但是不能load出来了

可以多次dump
dic = {'abc':(1,2,3)}
lst = ['aaa',123,'bbb',12.456]
with open('json_demo','w') as f:
    json.dump(lst,f)
    json.dump(dic,f)

但是load 就报错了

with open('json_demo') as f:
    ret = json.load(f)
    print(ret)
# 报错!

如何解决呢? 上面的问题咱们用dumps

没个字符后面加个回车,哎~ 一行一行来!

dic = {'abc':(1,2,3)}
lst = ['aaa',123,'bbb',12.456]
with open('json_demo','w') as f:
    str_lst = json.dumps(lst)
    str_dic = json.dumps(dic)
    f.write(str_lst+'
')
    f.write(str_dic+'
')

一行一行读出来,就行了哇!

with open('json_demo') as f:
    for line in f:
        ret = json.loads(line)
        print(ret)

补充:

中文格式的 ensure_ascii = False   字符串显示中文
dic = {'abc':(1,2,3),'country':'中国'}
ret = json.dumps(dic)  # {"abc": [1, 2, 3], "country": "u4e2du56fd"}
ret = json.dumps(dic,ensure_ascii = False)   # {"abc": [1, 2, 3], "country": "中国"}
dic_new = json.loads(ret)
print(dic_new)   # {'abc': [1, 2, 3], 'country': '中国'}
with open('json_demo','w',encoding='utf-8') as f:
    json.dump(dic,f,ensure_ascii=False)

json的其他参数,是为了用户看的更方便,但是会相对浪费存储空间
Serialize obj to a JSON formatted str.(字符串表示的json对象) 
Skipkeys:默认值是False,如果dict的keys内的数据不是python的基本类型(str,unicode,int,long,float,bool,None),设置为False时,就会报TypeError的错误。此时设置成True,则会跳过这类key 
ensure_ascii:,当它为True的时候,所有非ASCII码字符显示为uXXXX序列,只需在dump时将ensure_ascii设置为False即可,此时存入json的中文即可正常显示。) 
If check_circular is false, then the circular reference check for container types will be skipped and a circular reference will result in an OverflowError (or worse). 
If allow_nan is false, then it will be a ValueError to serialize out of range float values (nan, inf, -inf) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (NaN, Infinity, -Infinity). 
indent:应该是一个非负的整型,如果是0就是顶格分行显示,如果为空就是一行最紧凑显示,否则会换行且按照indent的数值显示前面的空白分行显示,这样打印出来的json数据也叫pretty-printed json 
separators:分隔符,实际上是(item_separator, dict_separator)的一个元组,默认的就是(‘,’,’:’);这表示dictionary内keys之间用“,”隔开,而KEY和value之间用“:”隔开。 
default(obj) is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. 
sort_keys:将数据根据keys的值进行排序。 
To use a custom JSONEncoder subclass (e.g. one that overrides the .default() method to serialize additional types), specify it with the cls kwarg; otherwise JSONEncoder is used.
其他参数说明
import json
data = {'username':['李华','二愣子'],'sex':'male','age':16}
json_dic2 = json.dumps(data, sort_keys=True, indent=4, separators=(',',':'),ensure_ascii=False)
print(json_dic2)
————————————————————
{
    "age":16,
    "sex":"male",
    "username":[
        "李华",
        "二愣子"
    ]
}

set不能被dump/dumps

3、

pickle
dumps
loads
dump
load

4、shelve (一般不用)
  只提供一个方法
原文地址:https://www.cnblogs.com/zhuangdd/p/12656568.html