4-05python语法基础-内置模块-json模块
序列化是什么?
现在的序列化都是转向一个字符串数据类型,
我们说的序列就是字符串,
为什么要千方百计的转换成为字符串呢?----是为了存储和传递
如果一个字典{"k":"v"}为什么要转成字符串
1,我往文件或者数据库里面写内容的时候是不能写入字典的,可以写入字符串,
2,还有在网络上传输的时候,我需要传递的是byte类型,怎么把字典转换成为一个byte类型呢,
就要先转换为字符串,然后字符串转换为byte类型,
基本就是这两种情况,需要序列化,
这种从数据类型转为字符串,就是序列化,
把字符串转换为数据类型的操作,就是反序列化,
json模块
json就是python里面的一个内置模块,用来做序列化的,
1,dumps序列化操作--把字典转换成字符串
如果仅仅是字典转为字符串,两种方法:str()以及json.dumps(),都是可以的,
但是比如要记住:str方法将字典变为单引号,json.dumps方法将字典变为双引号!!!!
注意:单引号双引号的区别
json序列化,必须是双引号的,所以要用json.dumps
初始字典为双引号-->转为双引号的字符串
import json
d={"name":"lisa","gender":"male"}
print(type(d)) # <class 'dict'>
# str_d=str(d)
# print("str_d:",str_d) # str_d: {'name': 'lisa', 'gender': 'male'}
# print("str_d的类型",type(str_d)) # str_d的类型 <class 'str'>
# 注意str函数,是把双引号的字典变成了单引号的字符串了,
json_d=json.dumps(d)
print("json_d:",json_d) # json_d: {"name": "lisa", "gender": "male"}
print("json_d的类型",type(json_d)) # json_d的类型 <class 'str'>
# 所以使用json.dumps,可以直接把双引号的字典,变成双引号的字符串,
初始字典为单引号-->转为双引号的字符串,
import json
d = {'name': 'lisa', 'gender': 'male'}
print(type(d)) # <class 'dict'>
str_d = str(d)
print("str_d:", str_d) # str_d: {'name': 'lisa', 'gender': 'male'}
print("str_d的类型", type(str_d)) # str_d的类型 <class 'str'>
# 注意单引号的字典,str函数,还是会转成单引号的字符串
json_d = json.dumps(d)
print("json_d:", json_d) # json_d: {"name": "lisa", "gender": "male"}
print("json_d的类型", type(json_d)) # json_d的类型 <class 'str'>
所以dumps,不管字典是单引号的还是双引号的,都是转为双引号的字符串,
2,loads反序列化操作--把字符串转换成字典
初始字符串为双引号-->转为字典
import json
jsonData = '{"name":"andy","age":11}'
print(type(jsonData)) # <class 'str'>
dict1 = json.loads(jsonData)
print(dict1) # {'name': 'andy', 'age': 11}
print(type(dict1)) # <class 'dict'>
初始字符串为单引号-->转为字典
import json
str1 = "{'name':'andy','age':11}"
dict1 = json.loads(str1)
print(type(dict1))
print(dict1)
# 报异常
# json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes:
# 需要用双引号括起来的属性名
所以你明白了,json,只能转换:只能转换外单引号,内双引号的字符串
背景:
在 python3 里,一个json是一个字典,形如 {"a":15}
json转换成字符串的话
那么,如果你要将它转换成字符串,也许你用的是str({"a":15}),这样转出来的,可能是是s= "{'a':'15'}",也就是说,里面的kv是单引号的。这个字符串,传到其他地方,再用json.loads(s)的时候会出错,json不支持单引号。
所以,假如你想把一个json结构,转成字符串,传递给远处,然后再重新解析成json结构,应该这样:
s = json.dumps({"a":15})
然后,把数据传到远端,然后再解析回来:
d = json.loads(s)
这样就不会出错了。
也支持列表,能一次性传多个结构
s = json.dumps([{"a":15}, {"b":20}])
然后,把数据传到远端,然后再解析回来:
d = json.loads(s)
所以一定要注意这个单引号和双引号的问题,
那么,内单引号,外双引号的字符串怎么转为字典呢????
方法1:
使用eval
str1 = "{'name':'andy','age':11}" # 这种不行,必须要有两个引号才行,
res = eval(str1)
print(type(res)) # print(type(res), res)
print(res) # {'name': 'andy', 'age': 11}
方法2:
eval:不安全,容易被用户恶意操作
ast.literal_eval:安全,专门用于字符串类型转换其他类型
import ast
str1 = "{'name':'andy','age':11}" # 这种不行,必须要有两个引号才行,
res = ast.literal_eval(str1)
print(type(res)) # print(type(res), res)
print(res) # {'name': 'andy', 'age': 11}
dump和load
上面讲了dumps和loads,还有dump,和load两个方法,这两个基本没有用过,
dump和dumps的区别:
dump是将对象序列化并保存到文件中
dumps是将对象序列化
load和loads的区别:
load将序列化字符串从文件读取并反序列化
loads将序列化字符串反序列化
一些特殊的报错
python报错json.decoder.JSONDecodeError: Invalid control character at: line 1 column 74453 (char 74452)
通过 python 的 json.loads(data) 方法报错时,加上 "strict=False" 即可,如
data = json.loads(data, strict=False)