1、dump和dumps格式化所有的基本数据类型为字符串
plain
import json
# dumps可以格式化所有的基本数据类型为字符串
data1 = json.dumps([]) # 列表
print(data1, type(data1))
data2 = json.dumps(2) # 数字
print(data2, type(data2))
data3 = json.dumps('3') # 字符串
print(data3, type(data3))
dict = {"name": "Tom", "age": 23} # 字典
data4 = json.dumps(dict)
print(data4, type(data4))
with open("test.json", "w", encoding='utf-8') as f:
# indent 超级好用,格式化保存字典,默认为None,小于0为零个空格
f.write(json.dumps(dict, indent=4))
json.dump(dict, f, indent=4) # 传入文件描述符,和dumps一样的结果
得到的输出结果如下:格式化所有的数据类型为str类型
plain
[] <class 'str'>
2 <class 'str'>
"3" <class 'str'>
{"name": "Tom", "age": 23} <class 'str'>
test.json中的内容
plain
{
"name": "Tom",
"age": 23
}
2、load和loads将字符串还原为dict
plain
import json
dict = '{"name": "Tom", "age": 23}' # 将字符串还原为dict
data1 = json.loads(dict)
print(data1, type(data1))
with open("test.json", "r", encoding='utf-8') as f:
data2 = json.loads(f.read()) # load的传入参数为字符串类型
print(data2, type(data2))
f.seek(0) # 将文件游标移动到文件开头位置
data3 = json.load(f)
print(data3, type(data3))
运行结果如下:
plain
{'name': 'Tom', 'age': 23} <class 'dict'>
{'name': 'Tom', 'age': 23} <class 'dict'>
{'name': 'Tom', 'age': 23} <class 'dict'>
常见的错误:
读取多行的JSON文件
假如要读取一个多行的JSON文件:
plain
{"坂": ["坂5742"]}
{"构": ["构6784"]}
{"共": ["共5171"]}
{"钩": ["钩94a9"]}
{"肮": ["肮80ae"]}
{"孤": ["孤5b64"]}
如果直接使用:
plain
with open(json_path, 'r') as f:
json_data = json.load(f)
就会报错:抛出异常JSONDecodeError。
plain
json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 17)
表示数据错误,数据太多,第2行第一列
因为json只能读取一个文档对象,有两个解决办法
1、单行读取文件,一次读取一行文件。
2、保存数据源的时候,格式写为一个对象。
单行读取文件:
plain
with open("test.json", "r", encoding='utf-8') as f:
for line in f.readlines():
json_data = json.loads(line)
但是这种做法还有个问题,如果JSON文件中包含空行,还是会抛出JSONDecodeError异常
plain
json.decoder.JSONDecodeError: Expecting value: line 2 column 1 (char 1)
可以先处理空行,再进行文件读取操作:
plain
with open("test.json", "r", encoding='utf-8') as f:
for line in f.readlines():
line = line.strip() # 使用strip函数去除空行
if len(line) != 0:
json_data = json.loads(line)
合并为一个对象
将json文件处理成一个对象文件。
plain
{"dict": [
{"坂": ["坂5742"]},
{"构": ["构6784"]},
{"共": ["共5171"]},
{"钩": ["钩94a9"]},
{"肮": ["肮80ae"]},
{"孤": ["孤5b64"]}
]}
然后再用:
plain
with open(json_path, 'r') as f:
json_data = json.loads(f.read())
总结:
json.dumps 将 Python 对象编码成 JSON 字符串
json.loads 将已编码的 JSON 字符串解码为 Python 对象
json.dump和json.load,需要传入文件描述符,加上文件操作。
JSON内部的格式要注意,一个好的格式能够方便读取,可以用indent格式化。
实例:序列化实体对象+
plain
def obj_to_json(entity=None):
"""
序列化实体对象
:param entity:
:return:
"""
json_data = {}
try:
data_str = json.dumps(entity, default=lambda obj: obj.__dict__, sort_keys=True, indent=4)
data = json.loads(data_str)
json_data = remove_empty_key(data)
except Exception as e:
print(e)
return json_data
plain
def remove_empty_key(data):
if isinstance(data, dict):
info_re = dict()
for key, value in data.items():
if isinstance(value, dict) or isinstance(value, list):
re = remove_empty_key(value)
if len(re):
info_re[key] = re
elif value not in [None]:
info_re[key] = value
return info_re
elif isinstance(data, list):
info_re = list()
for value in data:
if isinstance(value, dict) or isinstance(value, list):
re = remove_empty_key(value)
if len(re):
info_re.append(re)
elif value not in [None]:
info_re.append(value)
return info_re
else:
print('输入非列表/字典')