Python JSON:编码、解码与文件处理实战指南
Python JSON:编码、解码与文件处理实战指南
什么是 Python 中的 JSON?
JSON——JavaScript Object Notation 缩写——是最广泛使用的基于文本的数据交换格式。在 Python 中它直接映射到原生数据结构:对象变 dict,数组变 list,字符串、数字、布尔值、null 分别对应 str、int/float、bool、None。标准库 json 模块处理所有转换。
Python JSON 库
脚本中一次性导入模块:
import json
模块提供四个核心方法:
| 方法 | 描述 |
|---|---|
| dumps() | 将 Python 对象转为 JSON 字符串。 |
| dump() | 将 JSON 字符串直接写入文件对象。 |
| loads() | 将 JSON 字符串解析为 Python 对象。 |
| load() | 读取并解析 JSON 文件为 Python 对象。 |
Python 转 JSON(编码)
编码是将 Python 数据类型转为 JSON 的过程。默认映射如下:
| Python | JSON |
|---|---|
| dict | Object |
| list | Array |
| str/unicode | String |
| int/long | Number (int) |
| float | Number (real) |
| True | true |
| False | false |
| None | null |
使用 json.dumps() 示例:
import json
x = {
"name": "Ken",
"age": 45,
"married": True,
"children": ("Alice", "Bob"),
"pets": ["Dog"],
"cars": [
{"model": "Audi A1", "mpg": 15.1},
{"model": "Zeep Compass", "mpg": 18.1}
]
}
# 缩进美化并排序键
sorted_string = json.dumps(x, indent=4, sort_keys=True)
print(sorted_string)
输出:
{
"age": 45,
"cars": [
{"model": "Audi A1", "mpg": 15.1},
{"model": "Zeep Compass", "mpg": 18.1}
],
"children": ["Alice", "Bob"],
"married": true,
"name": "Ken",
"pets": ["Dog"]
}
用 json.dump() 写入文件:
with open('json_file.json', 'w') as file_write:
json.dump(x, file_write, indent=4, sort_keys=True)
运行后 json_file.json 将包含序列化数据。
JSON 转 Python(解码)
解码反向映射,将 JSON 字符串或文件转回原生 Python 对象。转换表与编码镜像:
| JSON | Python |
|---|---|
| Object | dict |
| Array | list |
| String | str |
| Number (int) | int |
| Number (real) | float |
| true | True |
| false | False |
| null | None |
使用 json.loads() 示例:
import json
person_data = '{"person": {"name": "Kenn", "sex": "male", "age": 28}}'
obj = json.loads(person_data)
print(obj)
print(type(obj))
print(obj.get('person'))
输出:
{'person': {'name': 'Kenn', 'sex': 'male', 'age': 28}}
<class 'dict'>
{'name': 'Kenn', 'sex': 'male', 'age': 28}
直接读取 JSON 文件:
with open('json_file.json') as f:
data = json.load(f)
print(data)
输出:
{'name': 'Ken', 'age': 45, ...}
紧凑与美化编码
网络传输用紧凑编码移除空白:
lst = ['a', 'b', 'c', {"4": 5, "6": 7}]
compact = json.dumps(lst, separators=(',', ':'))
print(compact)
输出:
["a","b","c",{"4":5,"6":7}]
人类可读用美化缩进:
dic = {"a": 4, "b": 5}
pretty = json.dumps(dic, indent=4, separators=(',', ': '))
print(pretty)
输出:
{
"a": 4,
"b": 5
}
编码复杂对象
json 模块无法序列化任意对象。处理 complex 数需提供 default 函数:
def complex_encode(o):
if isinstance(o, complex):
return [o.real, o.imag]
raise TypeError(f"{repr(o)} is not JSON serializable")
print(json.dumps(4 + 5j, default=complex_encode))
输出:
[4.0, 5.0]
解码复杂对象
用 object_hook 检测自定义标记并重建复数:
def is_complex(obj):
if "__complex__" in obj:
return complex(obj["real"], obj["img"])
return obj
complex_obj = json.loads('{"__complex__": true, "real": 4, "img": 5}', object_hook=is_complex)
print(complex_obj)
输出:
(4+5j)
序列化与反序列化类
JSONEncoder 和 JSONDecoder 类提供细粒度控制:
JSONEncoder.default(o)– 重写以序列化自定义对象。JSONEncoder.encode(o)– 返回 JSON 字符串。JSONEncoder.iterencode(o)– 迭代输出字符串。JSONDecoder.decode(s)– 解析 JSON 字符串。JSONDecoder.raw_decode(s)– 从给定索引开始解析。
示例:
from json.encoder import JSONEncoder
print(JSONEncoder().encode({"colour": ["red", "yellow", "green"]}))
从 URL 获取 JSON
用 requests 下载实时 JSON 源(如 CityBike NYC):
import json, requests
response = requests.get("https://feeds.citibikenyc.com/stations/stations.json")
bike_dict = json.loads(response.text)
print(bike_dict['stationBeanList'][0])
输出:
{'id': 487, 'stationName': 'E 20 St & FDR Drive', 'availableDocks': 24, ...}
处理 JSON 异常
主要异常是 json.JSONDecodeError,ValueError 子类。示例处理:
try:
with open('bad.json') as f:
data = json.load(f)
except json.JSONDecodeError as e:
print(f"Bad JSON: {e}")
特殊数值
RFC 8259 不允许 Infinity 或 NaN,但 Python 编码器以字符串表示:
print(json.dumps(float('inf')))
print(json.dumps(float('nan')))
输出:
Infinity NaN
JSON 中重复键
键多次出现时,Python json.loads() 仅保留最后一次:
json.loads('{"a": 1, "a": 2, "a": 3}') # -> {'a': 3}
命令行工具
json.tool 模块从命令行格式化验证 JSON:
$ echo '{"name": "Kings Arthur"}' | python3 -m json.tool
{
"name": "Kings Arthur"
}
Python 中 JSON 的优势
json模块原生支持。- 美化打印人类可读。
- 广泛用于 API、配置、数据存储。
- 语言无关且轻量。
局限性
- 无自定义编码器不支持自定义数据类型。
- 最大递归深度限制深层嵌套结构。
- 大文档完整加载可能内存密集。
Python JSON 速查表
| 函数 | 描述 |
|---|---|
| json.dumps(obj) | 序列化 Python 对象为 JSON 字符串。 |
| json.dump(obj, file) | 写 JSON 字符串到文件。 |
| json.dumps(obj, separators=(",", ":")) | 无空格紧凑表示。 |
| json.dumps(obj, indent=4) | 带缩进美化 JSON。 |
| json.dumps(obj, sort_keys=True) | 字典键按字母排序。 |
| json.dumps(obj, default=custom) | 编码不支持对象。 |
| JSONEncoder().encode(obj) | 通过编码器类手动序列化。 |
| json.loads(s) | 解析 JSON 字符串为 Python 对象。 |
| json.loads(s, object_hook=custom) | 自定义反序列化逻辑。 |
| JSONDecoder().decode(s) | 通过解码器类手动反序列化。 |
Python