序列化模块
什么叫序列化——将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化。
【一】为什么要有序列化模块
-
比如,我们在
python
代码中计算的一个数据需要给另外一段程序使用,那我们怎么给?- 现在我们能想到的方法就是存在文件里
- 然后另一个
python
程序再从文件里读出来。
-
但是我们都知道
- 对于文件来说是没有字典这个概念的
- 所以我们只能将数据转换成字典放到文件中。
-
你一定会问,将字典转换成一个字符串很简单,就是
str(dic)
就可以办到了- 为什么我们还要学习序列化模块呢?
-
没错序列化的过程就是从
dic
变成str(dic)
的过程。 -
现在你可以通过
str(dic)
- 将一个名为
dic
的字典转换成一个字符串,
- 将一个名为
-
但是你要怎么把一个字符串转换成字典呢?
- 聪明的你肯定想到了
eval()
,如果我们将一个字符串类型的字典str_dic
传给eval
,就会得到一个返回的字典类型了。 eval()
函数十分强大- 但是
eval
是做什么的? e
官方demo解释为:- 将字符串
str
当成有效的表达式来求值并返回计算结果。
- 将字符串
BUT!
强大的函数有代价。安全性是其最大的缺点。
- 但是
- 聪明的你肯定想到了
-
想象一下
- 如果我们从文件中读出的不是一个数据结构,
- 而是一句"删除文件"类似的破坏性语句
- 那么后果实在不堪设设想。
而使用eval
就要担这个风险。
-
所以
- 我们并不推荐用
eval
方法来进行反序列化操作(将str
转换成python
中的数据结构)
- 我们并不推荐用
【二】序列化的目的
- 1、以某种存储形式使自定义对象持久化;
- 2、将对象从一个地方传递到另一个地方。
- 3、使程序更具维护性。
【三】序列化模块之JSON
导入模块
import json
Json
模块提供了四个功能:
dumps
dump
loads
load
【1】loads和dumps
- 序列化
- 将一个字典转换成一个字符串
import json
dic = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
str_dic = json.dumps(dic)
print(type(str_dic), str_dic)
# <class 'str'> {"k3": "v3", "k1": "v1", "k2": "v2"}
注意
json转换完的字符串类型的字典中的字符串是由
""
表示的
- 反序列化
- 将一个字符串格式的字典转换成一个字典
import json
dic2 = json.loads(str_dic)
print(type(dic2),dic2)
#<class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
注意
要用
json
的loads
功能处理的字符串类型的字典中的字符串必须由""
表示
- 也可以处理嵌套的数据类型
import json
list_dic = [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}]
str_dic = json.dumps(list_dic)
print(type(str_dic), str_dic)
# <class 'str'> [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}]
import json
list_dic = [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}]
str_dic = json.dumps(list_dic)
list_dic2 = json.loads(str_dic)
print(type(list_dic2), list_dic2)
# <class 'list'> [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}]
【2】load和dump
- dump方法
- 接收一个文件句柄
- 直接将
字典
转换成json字符串
写入文件
import json
f = open('json_file','w')
dic = {'k1':'v1','k2':'v2','k3':'v3'}
json.dump(dic,f)
f.close()
- load方法
- 接收一个文件句柄
- 直接将文件中的
json字符串
转换成数据结构
返回
f = open('json_file')
dic2 = json.load(f)
f.close()
print(type(dic2),dic2)
【四】ensure_ascii关键字参数
import json
f = open('file', 'w')
json.dump({'国籍': '中国'}, f)
ret = json.dumps({'国籍': '中国'})
f.write(ret + '\n')
json.dump({'国籍': '美国'}, f, ensure_ascii=False)
ret = json.dumps({'国籍': '美国'}, ensure_ascii=False)
f.write(ret + '\n')
f.close()
【五】其它参数说明
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.
【六】json
的格式化输出
import json
data = {'username': ['李华', '二愣子'], 'sex': 'male', 'age': 16}
json_dic2 = json.dumps(data, sort_keys=True, indent=2, separators=(',', ':'), ensure_ascii=False)
print(json_dic2)
# {
# "age":16,
# "sex":"male",
# "username":[
# "李华",
# "二愣子"
# ]
# }
标签:模块,json,dic,JSON,str,dic2,序列化,字典
From: https://www.cnblogs.com/dream-ze/p/17457034.html