🚀 个人主页:xmp65535
🚀 专栏:python技术专栏
目录
[2.1 基本规则:](#2.1 基本规则:)
[2.2 写法示例:](#2.2 写法示例:)
[3.1 序列化和反序列:](#3.1 序列化和反序列:)
[3.2 Python json模块概览](#3.2 Python json模块概览)
[3.3 读取JSON数据](#3.3 读取JSON数据)
[3.4 写入JSON数据](#3.4 写入JSON数据)
[3.5 JSON进阶处理](#3.5 JSON进阶处理)
[3.5.1 美化输出(pretty-printing)](#3.5.1 美化输出(pretty-printing))
[3.5.2 处理复杂数据类型(日期、自定义对象等)](#3.5.2 处理复杂数据类型(日期、自定义对象等))
[3.5.3 解决编码问题](#3.5.3 解决编码问题)
[3.6 JSON与异常处理](#3.6 JSON与异常处理)
一、引言
介绍JSON的重要性以及它在现代编程和网络通信中的普遍应用,特别是在API和Web服务中。
二、JSON简介
JSON格式是一种用于结构化数据的轻量级文本交换格式。它采用完全独立于语言的文本格式,但使用了类似于JavaScript对象字面量的习惯性表示法。下面是JSON格式和写法的一些基本规则和示例:
2.1 基本规则:
- 数据在名称/值对中: 数据由键值对构成。键用双引号
"
包裹,后面跟一个冒号:
,然后是值。 - 数据由逗号分隔: 多个键值对由逗号
,
分隔。 - 花括号保存对象: 由花括号
{}
包围的是对象,表示一组无序的键值对。 - 方括号保存数组: 由方括号
[]
包围的是数组,表示值的有序集合。 - 字符串必须用双引号表示: JSON中的字符串必须由双引号
"
包围。 - 数字不用引号: 数值不必使用引号包围。
- 文件以UTF-8编码: JSON文本应该以UTF-8编码保存。
2.2 写法示例:
对象:
JSON对象是由花括号包围的键值对的集合。键(Key)必须是字符串,用双引号括起来,而值(Value)可以是字符串、数值、数组、布尔值、null,甚至另一个对象。键和值之间用冒号隔开,不同的键值对之间用逗号隔开。
python
{
"name": "John Doe",
"age": 30,
"isStudent": false,
"address": {
"street": "123 Main St",
"city": "Anytown"
}
}
数组
JSON数组是由方括号包围的有序值的集合。数组中的值可以是字符串、数值、对象、数组、布尔值或null。数组中的元素用逗号分隔。
python
[
"apple",
"banana",
"cherry"
]
数值
JSON数值可以是整数或浮点数,和大多数编程语言中的数值表示相似。
python
{
"integer": 25,
"float": 3.14159
}
字符串
JSON字符串是由双引号包围的字符序列。字符串是文本数据的表示方式,可以包含任何Unicode字符。
python
{
"greeting": "Hello, World!"
}
布尔值和null:
JSON布尔值只有两个,
true
和false
。它们用于表示逻辑值。null 在JSON中用于表示一个空值或不存在的值。
python
{
"isStudent": false,
"nickname": null
}
三、Python中的JSON
3.1 序列化和反序列:
在编程中,序列化和反序列化是两个互补的过程,用于将对象状态或数据结构转换为可存储或传输的格式(如JSON或XML),以及将这种格式重新转换回原来的对象状态或数据结构。
- **序列化(Serialization)**是将对象转换为字节流的过程,以便可以在网络上传输或保存到磁盘或数据库中。在序列化过程中,对象的状态和数据将被转换为二进制格式,使其能够被传输或存储。
举例: 当你把JSON数据写入一个TXT文件时,你实际上是在做序列化操作。你把在内存中的数据结构(例如,Python的字典、列表等)转换为JSON格式的字符串,并保存这个字符串到一个文本文件中。这个过程涉及到"序列化",因为你把内存中的数据结构转换为了一种能够被存储和传输的格式。
- **反序列化(Deserialization)**则是将序列化的字节流重新转换回对象的过程。通过反序列化,我们可以从字节流中重新构建出原始对象,并且恢复其状态和数据。
举例:如果在之后的某个时刻,你需要读取这个TXT文件并使用文件中的数据,你将需要把这个JSON格式的字符串"反序列化"成原来的数据结构,以便在代码中使用这些数据。这个过程通常涉及到解析这个字符串,并根据其内容重建原来的数据结构或对象。
3.2 Python json
模块概览
在Python中,
json
模块提供了一种简单的方法来编码和解码JSON数据。也就是说,它允许你将Python对象转换为JSON格式的字符串,也可以将JSON格式的字符串转换为Python对象。
基本功能:
以下是
json
模块的一些基本功能:
json.dumps(obj): 将Python对象编码成JSON字符串,这个过程称为序列化。你可以通过这个方法,将字典、列表、元组和原生数据类型转换为JSON格式的字符串。
json.loads(s): 将已编码的JSON字符串解码为Python对象,这个过程称为反序列化。该方法用于处理存储在字符串中的JSON数据。
json.dump(obj, fp) : 将Python对象编码成JSON格式,并将其写入到一个类文件对象
fp
中。这对于写入JSON文件非常有用。json.load(fp) : 读取类文件对象
fp
中的JSON数据,并将其解码为Python对象。这在读取JSON文件时非常常用。
3.3 读取JSON数据
- 如何使用
json.loads()
从字符串中读取JSON数据
python
import json
json_data = '{"name": "John", "age": 30, "city": "New York"}'
python_obj = json.loads(json_data)
print(python_obj["name"]) # 输出: John
- 使用
json.load()
从文件中读取JSON数据
python
import json
with open('data.json', 'r', encoding='utf-8') as file:
python_obj = json.load(file)
print(python_obj["age"]) # 输出: 30
3.4 写入JSON数据
- 使用
json.dumps()
将Python对象转换为JSON字符串
python
import json
python_dict = {"name": "Jane", "age": 25, "city": "Paris"}
json_data = json.dumps(python_dict)
print(json_data) # 输出: {"name": "Jane", "age": 25, "city": "Paris"}
- 使用
json.dump()
将Python对象写入文件
python
import json
python_dict = {"name": "Jane", "age": 25, "city": "Paris"}
with open('data.json', 'w', encoding='utf-8') as file:
json.dump(python_dict, file)
3.5 JSON进阶处理
3.5.1 美化输出(pretty-printing)
要美化JSON输出,你可以使用json.dumps()
方法的indent
参数。此外,sort_keys
参数可以让JSON数据中的键按字母顺序输出。
python
import json
data = {
"name": "John Doe",
"age": 30,
"isStudent": False,
"courses": ["Math", "Science"]
}
pretty_json = json.dumps(data, indent=4, sort_keys=True)
print(pretty_json)
3.5.2 处理复杂数据类型(日期、自定义对象等)
JSON标准本身不支持特定的复杂数据类型(如日期或自定义对象)。要处理这些类型,你需要在序列化和反序列化过程中进行自定义转换。
日期
对于日期类型,你可以在序列化时将其转换为字符串,在反序列化时再从字符串转换回日期类型。
python
import json
from datetime import datetime, date
def date_handler(obj):
if hasattr(obj, 'isoformat'):
return obj.isoformat()
else:
raise TypeError("Type is not serializable")
data = {
"name": "John Doe",
"birthday": date(1990, 4, 28)
}
json_data = json.dumps(data, default=date_handler)
print(json_data)
自定义对象
对于自定义对象,可以定义一个函数,将对象转换为可JSON序列化的形式。同样,也可以在反序列化时进行相应的转换。
python
class User:
def __init__(self, name, age):
self.name = name
self.age = age
# 自定义序列化函数
def encode_user(obj):
if isinstance(obj, User):
return {'name': obj.name, 'age': obj.age} # 或其他可识别的格式
raise TypeError("Object of type User is not JSON serializable")
user = User("Jane Doe", 32)
user_json = json.dumps(user, default=encode_user)
print(user_json)
3.5.3 解决编码问题
在处理非ASCII字符时,设置ensure_ascii
参数为False
可以避免将这些字符转换成ASCII字符编码的序列,从而可以直接在JSON字符串中使用原始字符。
python
data = {
"name": "张三",
"age": 30,
"isStudent": False
}
json_data = json.dumps(data, ensure_ascii=False)
print(json_data)
3.6 JSON与异常处理
- 处理JSON解析错误
python
import json
json_data = '{"name": "John", age: 30, "city": "New York"}' # 错误的JSON格式
try:
python_obj = json.loads(json_data)
except json.JSONDecodeError as e:
print(f"解析JSON时发生错误:{e}")
四、总结
强调掌握Python中的JSON处理对于进行有效的数据交换和应用程序开发的重要性。