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)

posted @ 2021-09-11 05:05  技术改变命运Andy  阅读(68)  评论(0编辑  收藏  举报