Python处理Json文件

本文小结JSON相关的一些知识点和读写方式,涉及内容

①. 序列化与反序列化; ②.Json数据格式转换及其读写; ③. 出错案例/非标准JSON文件处理

首先:import json

序列化与JSON文件

序列化Serialization,广泛地讲就是将内存中创建/生成的数据对象存为文件的过程

平时读写txt csv excel shapefile pickle json geojson都可以视为(反)序列化的过程

JSON文件

JSON全称是“JavaScript Object Notation”,是一种数据格式,js中的大量属性都是通过字典格式表示,因此json主要以字典格式存储。此外,GeoJSON是在json文件的基础上构建的一种,处理方式类似。

序列化(serialization)与反序列化(deserialization)

  1. 序列化指将数据结构、对象转换为可读取状态,如存为文件,以便下次或在其他环境中能够恢复到原来的状态;也称对象编组(marshlling)。

  2. 从一序列字节提取数据结果的反向操作则成为反序列化,也称解码组(unmarshlling) 。

python中的序列化模块主要有:pickle、json 等等

JSON对象

在未保存前其在内存中的表示即数据类型,类似于DataFrame与csv的关系

Python中的JSON序列化过程中,即在内存中的表示/数据类型:

  • 字典dict会编组为标准的JSON对象

  • listtuple转换为array

  • 字符及数值分别转换为string;numbers

数据类型转换:dumps()+loads()

json.dumps()就是序列化的函数,不带s的是用来读写的

我们可以直接将列表、字典等各种数据类型通过json.dumps(object)转换为json格式

当然,实际中更常用的是通过json.loads(json_string)读取json对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import json
# 其他对象转为json对象
mylist = [1,2,3,4,5]
mydic = {
"name":"h",
"age":24,
"money":1500}
data_json = json.dumps(mydic)
print(data_json) # {"name": "h", "age": 24, "money": 1500}
data_json = json.dumps(mydic, indent=4)
data_json # '{\n "name": "h",\n "age": 24,\n "money": 1500\n}'
print(data_json) # print()打印的话,会看待标准的字典样式,带4的缩进

# json转为原始对象
mydict = json.loads(data_json)

JSON文件写和读dump()+load()

一般而言json文件是由字典+列表多层嵌套组成,最终文件是字符串

写json文件

1
2
3
4
5
6
7
# 可以不转换将数据直接写入
mylist = [1,2,3,4,5]
with open("test.json",'w') as f:
json.dump(mydic, f, indent=4)

with open("test.json",'w') as f:
json.dump(mylist, f)

读json文件

1
2
with open("test.json",'r') as f:
mylist = json.load(f)

追加到json文件,追加无法像文本一样直接写入,需要读取原始json字典或者list,修改后再重新写出

1
2
3
4
5
6
7
8
9
#1.读取json文件
with open("test.json", 'r') as f:
mydic = json.load(f)
#2.修改,update好像是Python3.9及之后有的函数,也可以其他方式修改
x = {"x":[1,2,3,4]}
mydic.update(x)
#3.重新写入
with open("test.json", 'w') as f:
json.dump(mydic, f)

读写出错?——非标准json格式处理

出错调试案例

情况1:由于文件的多次序列与反序列化/读写,会导致格式不一致或非标准文件的产生

  • 如:读文件时出现:JSONDecodeError: Invalid control character at: line...,说明文件格式不标准,添加参数json.load(jf, strict=False)
1
2
with open('./pois.json','r') as f:
poi_list = json.load(f, strict=False)

情况2:文件是多个json对象组成的,理论上应该是存成[{},{}...]或类似的结构

  • 如通过记事本或notepad打开文件长这样,每行是一个json对象
1
2
3
{"created_at":"Sat Jul 01 13:00:00 +0000 2017","id":881135299081887744,...}
{"id":865709269722832896,"id_str":"865709269722832896","user_id"...}
...

处理逻辑:先读取文件再逐行/逐对象load加载

1
2
3
4
5
6
7
8
9
10
# 复合写法,将对象追加到list
tweets = []
for line in open('./dataset/tweets.json', 'r'):
tweets.append(json.loads(line))
# 拆开写
with open('./dataset/tweets.json','r') as f:
jsonstr_list = f.readlines()
for line in jsonstr_list:
x = json.loads(line)
tweets.append(x)

中文显示

输出文件中文编码显示ensure_ascii=False

1
2
with open(r"./china.json",'w', encoding='utf-8') as fp:
json.dump(ty_city,fp,indent=4,ensure_ascii=False)

部分参考

详细的也可以自己查或看以下链接

- Json in python

- Working With JSON Data in Python

- dump vs dumps