序列化的意思其实就是:
得到一个字符串的结果 过程就叫序列化
字典 / 列表 / 数字 /对象 -序列化->字符串
为什么要序列化?
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 (一般不用)
只提供一个方法