Python基础:JSON保存结构化数据(详解)
1. JSON概念
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,也易于机器解析和生产。
虽然JSON使用JavaScript语法来描述数据对象,但是JSON仍然独立于语言和平台,JSON解析器和JSON库支持许多不同的编程语言(C、Python、C++、Java、PHP、Go等均支持)。
1.1 JSON语法规则
1)数据在键/值对
(key-value pair) 中
2)数据由逗号,
分隔
3)使用斜杠\
来转义字符
4)大括号{}
保存对象
5)中括号[]
保存数组,数组可以包含多个对象
1.2 JSON的两种结构
1.2.1 对象(键/值对)
大括号{}
保存的对象是一个无序的 键/值对
集合。一个对象以左括号{
开始, 右括号}
结束。一个键(key)和一个值(value)之间用冒号:
分隔,键/值对
之间用逗号,
分隔。
# 对象语法规则
{key1 : value1, key2 : value2, ... keyN : valueN }
# 对象示例
{
"name": "John",
"age": 30,
"city": "New York"
}
1.2.2 数组(array)
中括号[]
保存的数组是值(value)的有序集合。一个数组以左中括号[
开始, 右中括号]
结束,值之间使用逗号,
分隔。
数组的值(Value)可以是字符串、数值、布尔值、Null、对象、数组,且它们之间还可以进行嵌套。
#数组语法规则
[
{ key1 : value1-1 , key2:value1-2 },
{ key1 : value2-1 , key2:value2-2 },
{ key1 : value3-1 , key2:value3-2 },
...
{ key1 : valueN-1 , key2:valueN-2 },
]
# 数组示例
{
"sites": [
{"name":"百度", "url": "http://www.baidu.com"},
{"name":"谷歌", "url": "http://www.google.com"},
{"name":"微博", "url": "http://www.weibo.com"}
]
}
1.3 JSON支持的数据类型
对象(object):由花括号{}
包围的键值对集合。
数组(array):由方括号[]
包围的值的有序列表。
字符串(string):由双引号括起来的Unicode字符序列。
数字(number):整数或浮点数。
布尔值(true/false):表示真或假。
null:表示空值。
1.4 较复杂的JSON示例
{
"name": "Alice",
"age": 25,
"isStudent": true,
"grades": [90, 85, 92],
"address": {
"street": "123 Main St",
"city": "Anytown",
"zip": "12345"
}
}
2. Python中处理JSON格式数据
字符串可以很容易地写入文件或从文件中读取。 数字则更麻烦一些,因为 read()
方法只返回字符串,而字符串必须传给 int() 这样的函数,它接受 '123'
这样的字符串并返回其数值 123
。 当想要保存嵌套列表和字典等更复杂的数据类型时,手动执行解析和序列化操作将会变得非常复杂。
Python 允许使用流行的数据交换格式 JSON (JavaScript Object Notation),而不是让用户持续编写和调试代码来将复杂的数据类型存入文件中。 标准库模块json
可以接受带有层级结构的 Python 数据,并将其转换为字符串表示形式;这个过程称为serializing
。 根据字符串表示形式重建数据则称为 deserializing
。 在序列化和反序列化之间,用于代表对象的字符串可以存储在文件或数据库中,或者通过网络连接发送到远端主机。
2.1 导入 json 模块
首先要导入json
模块,实际上就是JSON编码和解码器的作用。
import json
json 模块主要包含了2种类型的函数:
json.dumps()
:对数据进行编码。json.loads()
:对数据进行解码。
在json
的编解码过程中,Python的原始类型与json
类型会相互转换。
Python编码为JSON类型转换对应表:
JSON解码为Python类型转换对应表:
2.2 Python编码为JSON格式数据
2.2.1 使用dumps方法
json.dumps()
可以将Python对象编码为JSON格式的字符串.
json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
import json
# 列表对象
fruits = ["apple", "banana", "orange"]
# 编码为 JSON 字符串
json_string = json.dumps(fruits, indent=2)
print('原始列表:',repr(fruits))
print('JSON对象:',json_string)
import json
# 字典对象
person = {
"name": "Alice",
"age": 25,
"is_student": True,
"grades": [90, 85, 92]
}
# 编码为 JSON 字符串
json_string = json.dumps(person, indent=2)
print('原始字典:',person)
print('JSON对象:',json_string)
# 其他类型示例
import json
data_str = 'Hello, JSON!'
data_num = 41.2
data_bool = True
data_none = None
json_str = json.dumps(data_str, indent=2)
json_num = json.dumps(data_num, indent=2)
json_bool = json.dumps(data_bool, indent=2)
json_none = json.dumps(data_none, indent=2)
print("String的JSON对象:", json_str)
print("Number的JSON对象:", json_num)
print("Boolean的JSON对象:", json_bool)
print("None的JSON对象:", json_none)
2.2.2 使用dump方法
json.dump()
方法可以将Python对象编码为JSON格式的字符串并将其写入文件对象。
json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
使用这个 转换表 将obj
序列化为 JSON 格式化流形式的fp
(支持 .write()
的file-like object
)。
如果 skipkeys
是true
(默认为False
),那么那些不是基本对象(包括str
,int
、float
、bool
、None
)的字典的键会被跳过;否则引发一个TypeError
。
json
模块始终产生 str
对象而非bytes
对象。因此,fp.write()
必须支持 str
输入。
如果ensure_ascii
是 true
(即默认值),输出保证将所有输入的非 ASCII
字符转义。如果 ensure_ascii
是 false
,这些字符会原样输出。
如果 check_circular
为假值 (默认值: True
),那么容器类型的循环引用检查会被跳过并且循环引用会引发 RecursionError
(或者更糟的情况)。
如果 allow_nan
是 false
(默认为True
),那么在对严格 JSON 规格范围外的float
类型值(nan
、inf
和 -inf
)进行序列化时会引发一个 ValueError
。如果 allow_nan
是true
,则使用它们的 JavaScript 等价形式(NaN
、Infinity
和-Infinity
)。
如果indent
是一个非负整数或者字符串,那么 JSON 数组元素和对象成员会被美化输出为该值指定的缩进等级。 如果缩进等级为零、负数或者 ""
,则只会添加换行符。 None
(默认值) 选择最紧凑的表达。 使用一个正整数会让每一层缩进同样数量的空格。 如果indent
是一个字符串 (比如 "\t"
),那个字符串会被用于缩进每一层。
import json
data = {
'name': 'Scott',
'age': 18,
'is_student':True,
'grades':[100,99,60,88],
'address':{'street':'东风东路757号','city':'广州','province':'广东省','zip':51000}
}
with open('output_json.json','w',encoding='utf-8') as file_json:
json.dump(data,file_json,ensure_ascii=False,indent=2)
2.3 Python解码JSON格式数据
2.3.1 使用loads方法
json.loads()
方法将包含在JSON字符串中的数据解码为Python对象。
json.loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
import json
# JSON 格式的字符串
json_string = '{"name": "Alice", "age": 25, "is_student": true, "grades": [90, 85, 92]}'
# 解码为 Python 对象
python_object = json.loads(json_string)
print(python_object)
2.3.2 使用load方法
json.load()
方法将从JSON文件中读取JSON数据并将其解码为相应的Python对象。
json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
使用这个 转换表 将fp
(一个支持 .read()
并包含一个 JSON 文档的 text file
或者binary file
) 反序列化为一个 Python 对象。
object_hook
是一个将附带任意已解码的对象字面值 (即 dict)
来调用的可选函数。 object_hook 的返回值会代替 dict 使用。 此特性可被用于实现自定义解码器 。
object_pairs_hook
是一个可选的函数,它会被调用于每一个有序列表对解码出的对象字面量。
object_pairs_hook
的返回值将会取代原本的 dict
。这一特性能够被用于实现自定义解码器。如果 object_hook
也被定义,object_pairs_hook
优先。
import json
with open('output_json.json','r',encoding='utf-8') as file_json:
load_data = json.load(file_json)
print(load_data)
3. 应用场景
Python编程有很多涉及JSON文件或数据的场景,如爬虫时获取的网页信息、用于web配置文件、简单的用户数据持久化、游戏文件配置等等,很多都是简单方便的应用。
3.1 配置文件存储
JSON常用于存储配置信息,例如一个Web应用的配置文件:
# Web应用配置
web_app_config = {
"app_name": "MyApp",
"debug_mode": True,
"database": {
"host": "localhost",
"port": 5432,
"username": "admin",
"password": "secret"
},
"allowed_users": ["user1", "user2", "user3"]
}
# 将配置信息写入JSON文件
with open('config.json', 'w') as json_file:
json.dump(web_app_config, json_file, indent=4)
3.2 API相应处理
当与API进行交互时,常常会收到JSON格式的响应。
import requests
# 发送API请求
response = requests.get('https://api.example.com/data')
# 将JSON响应转换为Python数据结构
api_data = json.loads(response.text)
# 处理数据
print(api_data)
3.3 数据持久化
JSON可用于数据的持久化存储,适用于小型应用或原型。例如,存储用户信息。
# 用户信息
users = [
{"id": 1, "name": "Alice", "age": 25},
{"id": 2, "name": "Bob", "age": 30},
{"id": 3, "name": "Charlie", "age": 22}
]
# 将用户信息写入JSON文件
with open('users.json', 'w') as json_file:
json.dump(users, json_file, indent=4)
3.4 配置管理
在软件开发中,JSON经常用于配置管理。例如,一个游戏的配置文件:
# 游戏配置
game_config = {
"title": "MyGame",
"resolution": {"width": 1920, "height": 1080},
"sound": {"volume": 80, "mute": False},
"controls": {"up": "W", "down": "S", "left": "A", "right": "D"}
}
# 将游戏配置写入JSON文件
with open('game_config.json', 'w') as json_file:
json.dump(game_config, json_file, indent=4)
4. 参考
官网:
https://docs.python.org/zh-cn/3/tutorial/inputoutput.html#saving-structured-data-with-json
https://docs.python.org/3/library/json.html
菜鸟教程:
https://www.runoob.com/json/json-tutorial.html
https://www.runoob.com/python3/python3-json.html