JSON文件存储

news/2024/10/8 19:48:08

JSON 文件存储

  JSON,全称为 JavaScript Object Notation, 也就是 JavaScript 对象标记,通过对象和数组的组合来表示数据,构造简洁但是结构化程度非常高,是一种轻量级的数据交换格式。

对象和数组

  在 JavaScript 语言中,一切皆为对象。因此任何支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。其中对象和数组是比较特殊且常用的两种类型。

  对象在JavaScript中是使用花括号 {} 包裹起来的内容,数据结构为 {key1:value1, key2:value2, ...} 的键值对结构。在面向对象的语言中,key 表示对象的属性,value 表示属性对应的值。键名可以使用整数和字符串来表示。值的类型可以是任意类型。

  数组在JavaScript中是方括号 [] 包裹起来的内容,数据结构为 ["java", "javascript", "vb", ...] 的索引结构。在 JavaScript 中,数组是一种比较特殊的数据类型,它也可以像对象那样使用键值对结构,但还是索引用得多。同样,值的类型可以是任意类型。

  一个 JSON 对象可以写为如下形式:

[{"name": "Bob","gender": "male","birthday": "1992-10-18"
}, {"name": "Selina","gender": "female","birthday": "1995-10-18"
}]

  由中括号包围的就相当于数组,数组中的每个元素可以是任意类型,这个实例中的元素是对象,由{}包围。

  JSON 可以由以上两种形式自由组合而成,可以无限次嵌套,结构清晰,是数据交换的极佳方式。

读取 JSON

  Python 提供了简单易用的 JSON 库来实现 JSON 文件的读写操作,可以调用 JSON 库的 loads 方法将 JSON 文本字符串转为 JSON 对象,可以通过 dumps() 方法将 JSON 对象转为文本字符串。

例如,这里有一段 JSON 形式的字符串,它是 str 类型,我们用 Python 将其转换为可操作的数据结构,如列表或字典:

import jsonstr = '''
[{"name": "Bob","gender": "male","birthday": "1992-10-18"
}, {"name": "Selina","gender": "female","birthday": "1995-10-18"
}]
'''print(type(str))
data = json.loads(str)
print(data)
print(type(data))

运行结果如下:

<class 'str'>
[{'name': 'Bob', 'gender': 'male', 'birthday': '1992-10-18'}, {'name': 'Selina', 'gender': 'female', 'birthday': '1995-10-18'}]
<class 'list'>

  使用 loads 方法将字符串转为 JSON 对象。由于最外层是中括号,所以最终的类型是列表类型。

  这样一来就可以用索引来获取对应的内容了。例如,如果想取第一个元素里的 name 属性,就可以使用如下方式:

print(data[0]['name'])
print(data[0].get('name'))

得到的结果都是:

Bob
Bob

  通过中括号加 0 索引,可以得到第一个字典元素,然后再调用其键名即可得到相应的键值。获取键值时有两种方式,一种是中括号加键名,另一种是通过 get 方法传入键名。这里推荐使用 get 方法,这样如果键名不存在,则不会报错,会返回 None。另外,get 方法还可以传入第二个参数(即默认值),示例如下:

print(data[0].get('age'))
print(data[0].get('age', 25))

运行结果:

None
25

  尝试获取年龄 age,其实在原字典中该键名不存在,此时默认会返回 None。如果传入第二个参数(即默认值),那么在不存在的情况下返回该默认值。

  值得注意的是,JSON 的数据需要用双引号来包围,不能使用单引号。例如,若使用如下形式表示,则会出现错误:

import jsonstr = '''
[{'name': 'Bob','gender': 'male','birthday': '1992-10-18'
}]
'''
data = json.loads(str)

运行结果:

json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 3 column 5 (char 8)

  会出现 JSON 解析错误的提示。因为这里数据用单引号来包围,请千万注意 JSON 字符串的表示需要用双引号,否则 loads 方法会解析失败。

  下面实例从 JSON 文本中读取内容,例如这里有一个 data.json 文本文件,其内容是刚才定义的 JSON 字符串,可以先将文本文件内容读出,然后再利用 loads 方法转化:

import jsonwith open('data.json', 'r') as file:str = file.read()data = json.loads(str)print(data)

运行结果如下:

[{'name': 'Bob', 'gender': 'male', 'birthday': '1992-10-18'}, {'name': 'Selina', 'gender': 'female', 'birthday': '1995-10-18'}]

  还可以使用open方法读取文本文件,使用的是默认的读模式,编码指定为utf-8,并文件操作对象赋值为file。然后调用file对象的read方法读取了文本中的所有内容,赋值为str。接着再调用loads方法解析JSON字符串,将其转换为JSON对象。

  还有更简便的写法,可以直接使用load方法传入文件操作对象,同样也可以将文本转化为JSON对象,写法如下:

import jsondata = json.load(open('data.json', encoding='utf-8'))
print(data)

  这里使用的是load方法,而不是loads方法。前者的参数是一个文件操作对象,后者的参数是一个JSON字符串。

  两种写法的 运行结果完全一样。只不过load方法时将整个文件中的内容转换为JSOn对象,而loads方法可以更灵活地控制要转换的内容。两种方法可以在适当的环境下选择使用。

输出 JSON

  可以调用 dumps 方法将 JSON 对象转化为字符串。例如,将上例中的列表重新写入文本:

import jsondata = [{'name': 'Bob','gender': 'male','birthday': '1992-10-18'
}]
with open('data.json', 'w') as file:file.write(json.dumps(data))

  利用 dumps 方法,可以将 JSON 对象转为字符串,然后再调用文件的 write 方法写入文本。

运行结果:

  如果想保存 JSON 的格式,可以再加一个参数 indent,代表缩进字符个数。示例如下:

with open('data.json', 'w') as file:file.write(json.dumps(data, indent=2))

运行结果:

  这样得到的内容会自动带缩进,格式会更加清晰。

  如果 JSON 中包含中文字符,会怎么样呢?将之前的 JSON 的部分值改为中文,再用之前的方法写入到文本:

import jsondata = [{'name': ' 王伟 ','gender': ' 男 ','birthday': '1992-10-18'
}]
with open('data.json', 'w') as file:file.write(json.dumps(data, indent=2))
运行结果:

  结果中中文字符都变成了 Unicode 字符,这并不是想要的结果。

  为了输出中文,还需要指定参数 ensure_ascii 为 False,另外还要规定文件输出的编码:

with open('data.json', 'w', encoding='utf-8') as file:file.write(json.dumps(data, indent=2, ensure_ascii=False))
运行结果:
with open('data.json', 'w', encoding='utf-8') as file:
    file.write(json.dumps(data, indent=2, ensure_ascii=False))

这样就可以输出 JSON 为中文了。

  类比loads和load方法,dumps同样也有对应的dump方法,可以直接JSON对象全部写入文件中,因此上述方法也可以写成如下形式:

json.dump(data, open('data.json', 'w', encoding='utf-8'), indent=2, ensure_ascii=False)

  第一个参数为JSON对象,第二个参数可以传入文件操作对象,其他的indent、ensure_ascii对象保持不变,运行结果是一样的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hjln.cn/news/42516.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

关于类、继承、接口的复习(1)

均使用这个层次结构:多态:一个对象变量可以指示多种实际类型 动态绑定:一个对象变量在运行时能够自动选择适合的方法 注:对象变量是一种“引用”,引用不同块对象的内存,“指示多种实际类型”就是一个对象变量可以在不同情况下引用了多种有继承关系的类型,规则是——对象…

南昌航空大学软件学院-23201930-刘靖辉-第二次blog作业

1. 前言 2. 设计与分析2.1 OOP-4:答题判题程序12.1.1 题目2.1.2 源码2.1.3 评价与分析2.1.4 踩坑心得2.1.5 改进建议2.2 OOP-5:答题判题程序22.2.1 题目2.2.2 源码2.2.3 评价与分析2.2.4 踩坑心得2.2.5 改进建议2.3 OOP-6:答题判题程序32.3.1 题目2.3.2 源码2.3.3 评价与分析…

跟思兼学Klipper(30):使用辅助宏调整3D打印机无感归位堵转检测阈值

又名《调整堵转检测阈值降低创想三维 K1C 打印机无感归位啪啪声》 前言 原创文章,转载引用务必著名链接,水平有限,如有疏漏,欢迎指正交流。 文章如有更新请访问 DFRobot 社区及 cnblogs 博客园,前者内容较全,后者排版及阅读体验更佳。 手中的创想三维 K1C 3D 打印机目前使…

分组排名

问题:按A列数据分组降序排名函数公式解决:=MATCH(C2,SORT(FILTER(C$2:C$20,A$2:A$20=A2),,-1),)Filter部分提取相同配货仓的销售金额 Sort部分将同组内销售金额降序排序 Match部分查找每个值在降序排序后数据中的位置,相当于获取排名

“交叉引用”的条件格式

问题:设置条件格式,高显指定姓名和指定姓名与月份的数据条件格式解决:使用公式:=($D2=$A$2)*(D$2=$B$2)+(D$2=$B$2)*(ROW(D2)=2)($D2=$A$2)*(D$2=$B$2):高显指定月份和姓名的数据 (D$2=$B$2)*(ROW(D2)=2):高显指定姓名第一行的数据

kali2022安装教程(附安装包)

第一步:下载镜像文件 百度网盘下载[链接:https://pan.baidu.com/s/1efRQGFTbq6Kgw9axLOmWzg?pwd=emxf () 第二步:打开Vmware创建新的虚拟机,选择高级,然后下一步直接默认下一步选择稍后安装然后下一步kali属于Debian系统所以这里直接选择Debian6 64位进行命名和选择安装位…