Python 和 JSON:完整教程及示例
使用 json 模块掌握 Python 中的 JSON。学习解析、生成和操作 JSON 数据的实用示例和最佳实践。
Big JSON Team
• Technical WriterExpert in JSON data manipulation, API development, and web technologies. Passionate about creating tools that make developers' lives easier.
# Python 和 JSON:完整教程及示例
Python 的内置 json 模块使处理 JSON 数据变得简单高效。本综合指南涵盖了从基本解析到高级技术的所有内容,并提供了实际示例。
Python json 模块简介
json 模块是 Python 标准库的一部分,无需安装:
import json
主要功能
- json.loads():解析 JSON 字符串
- json.load():从文件读取 JSON
- json.dumps():将对象转换为 JSON 字符串
- json.dump():将对象写入 JSON 文件
解析 JSON
json.loads() - 解析 JSON 字符串
将 JSON 字符串转换为 Python 对象:
import json
json_string = '{"name": "张三", "age": 30, "city": "北京"}'
data = json.loads(json_string)
print(data['name']) # "张三"
print(type(data)) # <class 'dict'>
json.load() - 从文件读取
从文件加载 JSON 数据:
import json
with open('data.json', 'r', encoding='utf-8') as file:
data = json.load(file)
print(data)
data.json:
{
"users": [
{"name": "张三", "age": 30},
{"name": "李四", "age": 25}
]
}
输出:
{'users': [{'name': '张三', 'age': 30}, {'name': '李四', 'age': 25}]}
处理解析错误
import json
json_string = '{"name": "张三", "age": 30,}' # 尾随逗号
try:
data = json.loads(json_string)
except json.JSONDecodeError as e:
print(f"错误:{e}")
print(f"行 {e.lineno},列 {e.colno}")
生成 JSON
json.dumps() - 转换为 JSON 字符串
将 Python 对象转换为 JSON 字符串:
import json
data = {
"name": "王五",
"age": 28,
"active": True,
"skills": ["Python", "JavaScript"],
"address": None
}
json_string = json.dumps(data, ensure_ascii=False)
print(json_string)
# {"name": "王五", "age": 28, "active": true, "skills": ["Python", "JavaScript"], "address": null}
美化输出
使用缩进使 JSON 可读:
json_string = json.dumps(data, indent=2, ensure_ascii=False)
print(json_string)
输出:
{
"name": "王五",
"age": 28,
"active": true,
"skills": [
"Python",
"JavaScript"
],
"address": null
}
json.dump() - 写入文件
将 Python 对象保存到 JSON 文件:
import json
data = {
"company": "科技创新",
"employees": [
{"name": "张三", "role": "开发者"},
{"name": "李四", "role": "设计师"}
]
}
with open('output.json', 'w', encoding='utf-8') as file:
json.dump(data, file, indent=2, ensure_ascii=False)
数据类型映射
Python 到 JSON
| Python 类型 | JSON 类型 |
|------------|----------|
| dict | object |
| list, tuple | array |
| str | string |
| int, float | number |
| True | true |
| False | false |
| None | null |
示例:import json
python_data = {
"字典": {"key": "value"},
"列表": [1, 2, 3],
"元组": (4, 5, 6),
"字符串": "文本",
"整数": 42,
"浮点数": 3.14,
"布尔值": True,
"空值": None
}
json_string = json.dumps(python_data, ensure_ascii=False)
print(json_string)
JSON 到 Python
| JSON 类型 | Python 类型 |
|----------|-----------|
| object | dict |
| array | list |
| string | str |
| number (int) | int |
| number (real) | float |
| true | True |
| false | False |
| null | None |
常用选项
ensure_ascii
控制非 ASCII 字符的处理:
data = {"name": "张三", "city": "北京"}
# 默认(转义非 ASCII)
print(json.dumps(data))
# {"name": "\u5f20\u4e09", "city": "\u5317\u4eac"}
# ensure_ascii=False(保留 Unicode)
print(json.dumps(data, ensure_ascii=False))
# {"name": "张三", "city": "北京"}
sort_keys
按字母顺序排序键:
data = {"z": 1, "a": 2, "m": 3}
print(json.dumps(data, sort_keys=True))
# {"a": 2, "m": 3, "z": 1}
separators
自定义分隔符以压缩输出:
data = {"name": "张三", "age": 30}
# 默认
print(json.dumps(data))
# {"name": "张三", "age": 30}
# 压缩
print(json.dumps(data, separators=(',', ':')))
# {"name":"张三","age":30}
indent
控制缩进级别:
data = {"name": "张三", "skills": ["Python", "Java"]}
# 2 空格缩进
print(json.dumps(data, indent=2, ensure_ascii=False))
# 4 空格缩进
print(json.dumps(data, indent=4, ensure_ascii=False))
# 制表符缩进
print(json.dumps(data, indent='\t', ensure_ascii=False))
处理复杂数据
嵌套结构
import json
data = {
"company": "科技创新",
"departments": [
{
"name": "工程",
"employees": [
{"name": "张三", "role": "开发者"},
{"name": "李四", "role": "测试"}
]
},
{
"name": "设计",
"employees": [
{"name": "王五", "role": "UI 设计师"}
]
}
]
}
# 访问嵌套数据
print(data['departments'][0]['employees'][0]['name']) # "张三"
# 转换为 JSON
json_string = json.dumps(data, indent=2, ensure_ascii=False)
print(json_string)
自定义对象
默认参数
import json
from datetime import datetime, date
class Employee:
def __init__(self, name, hire_date):
self.name = name
self.hire_date = hire_date
def json_serializer(obj):
"""自定义 JSON 序列化器"""
if isinstance(obj, (datetime, date)):
return obj.isoformat()
if isinstance(obj, Employee):
return {
"name": obj.name,
"hire_date": obj.hire_date
}
raise TypeError(f"类型 {type(obj)} 不可 JSON 序列化")
emp = Employee("张三", date(2020, 1, 15))
json_string = json.dumps(emp, default=json_serializer, ensure_ascii=False)
print(json_string)
# {"name": "张三", "hire_date": "2020-01-15"}
JSONEncoder 子类
import json
from datetime import datetime
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
if isinstance(obj, set):
return list(obj)
return super().default(obj)
data = {
"timestamp": datetime.now(),
"tags": {"python", "json", "教程"}
}
json_string = json.dumps(data, cls=CustomEncoder, ensure_ascii=False)
print(json_string)
处理日期时间
import json
from datetime import datetime
# 序列化
now = datetime.now()
data = {
"event": "会议",
"time": now.isoformat()
}
json_string = json.dumps(data, ensure_ascii=False)
print(json_string)
# 反序列化
loaded = json.loads(json_string)
meeting_time = datetime.fromisoformat(loaded['time'])
print(meeting_time)
实际示例
示例 1:处理 API 响应
import json
import requests
# 获取数据
response = requests.get('https://api.example.com/users')
data = response.json() # 或 json.loads(response.text)
# 处理数据
for user in data['users']:
print(f"姓名:{user['name']},年龄:{user['age']}")
# 保存到文件
with open('users.json', 'w', encoding='utf-8') as f:
json.dump(data, f, indent=2, ensure_ascii=False)
示例 2:配置文件
import json
# 读取配置
def load_config(filename):
with open(filename, 'r', encoding='utf-8') as f:
return json.load(f)
# 保存配置
def save_config(filename, config):
with open(filename, 'w', encoding='utf-8') as f:
json.dump(config, f, indent=2, ensure_ascii=False)
# 使用
config = load_config('config.json')
config['database']['port'] = 5432
save_config('config.json', config)
config.json:
{
"database": {
"host": "localhost",
"port": 5432,
"name": "mydb"
},
"logging": {
"level": "INFO"
}
}
示例 3:数据转换
import json
# CSV 到 JSON
def csv_to_json(csv_file, json_file):
import csv
data = []
with open(csv_file, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
data.append(row)
with open(json_file, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=2, ensure_ascii=False)
# 使用
csv_to_json('data.csv', 'data.json')
示例 4:验证 JSON
import json
def validate_json(json_string):
"""验证 JSON 字符串"""
try:
json.loads(json_string)
return True, "有效的 JSON"
except json.JSONDecodeError as e:
return False, f"无效的 JSON:{e}"
# 测试
test_cases = [
'{"name": "张三"}', # 有效
'{"name": "张三",}', # 无效(尾随逗号)
"{'name': 'Zhang San'}", # 无效(单引号)
]
for test in test_cases:
valid, message = validate_json(test)
print(f"{test[:20]}... → {message}")
示例 5:合并 JSON 文件
import json
from pathlib import Path
def merge_json_files(output_file, input_files):
"""合并多个 JSON 文件"""
merged = {}
for file in input_files:
with open(file, 'r', encoding='utf-8') as f:
data = json.load(f)
merged.update(data)
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(merged, f, indent=2, ensure_ascii=False)
# 使用
merge_json_files('merged.json', 'file1.json', 'file2.json', 'file3.json')
性能优化
大文件处理
对于大型 JSON 文件,考虑流式处理:
import json
def process_large_json(filename):
"""逐块处理大型 JSON"""
with open(filename, 'r', encoding='utf-8') as f:
# 对于非常大的文件,考虑使用 ijson
data = json.load(f)
# 逐项处理
for item in data['items']:
process_item(item)
def process_item(item):
# 处理单个项目
pass
使用 ujson
对于更快的性能,使用 ujson:
pip install ujson
import ujson
# 更快的解析
data = ujson.loads(json_string)
# 更快的序列化
json_string = ujson.dumps(data)
常见错误和解决方案
1. JSONDecodeError
问题:json.JSONDecodeError: Expecting property name enclosed in double quotes
解决方案:
# 错误:单引号
bad = "{'name': 'Zhang San'}"
# 正确:双引号
good = '{"name": "Zhang San"}'
2. Object is not JSON serializable
问题:TypeError: Object of type datetime is not JSON serializable
解决方案:
from datetime import datetime
import json
data = {"time": datetime.now()}
# 使用自定义序列化器
json.dumps(data, default=str)
# 或
json.dumps(data, default=lambda x: x.isoformat() if isinstance(x, datetime) else None)
3. 编码错误
问题:UnicodeEncodeError: 'ascii' codec can't encode characters
解决方案:
# 使用 ensure_ascii=False
json.dumps(data, ensure_ascii=False)
# 或指定编码
with open('file.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False)
最佳实践
1. 始终指定编码
# 推荐
with open('file.json', 'r', encoding='utf-8') as f:
data = json.load(f)
2. 使用上下文管理器
# 推荐
with open('file.json', 'w', encoding='utf-8') as f:
json.dump(data, f)
# 不推荐
f = open('file.json', 'w')
json.dump(data, f)
f.close() # 容易忘记
3. 处理异常
import json
try:
with open('data.json', 'r', encoding='utf-8') as f:
data = json.load(f)
except FileNotFoundError:
print("文件未找到")
except json.JSONDecodeError as e:
print(f"无效的 JSON:{e}")
except Exception as e:
print(f"错误:{e}")
4. 验证数据
import json
data = json.loads(json_string)
# 验证必需的字段
assert 'name' in data, "缺少 'name' 字段"
assert isinstance(data['age'], int), "'age' 必须是整数"
5. 使用 ensure_ascii=False 处理中文
data = {"name": "张三", "city": "北京"}
# 推荐
json.dumps(data, ensure_ascii=False)
# {"name": "张三", "city": "北京"}
# 不推荐
json.dumps(data)
# {"name": "\u5f20\u4e09", "city": "\u5317\u4eac"}
高级技术
JSON Schema 验证
from jsonschema import validate, ValidationError
import json
schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "number", "minimum": 0}
},
"required": ["name"]
}
data = {"name": "张三", "age": 30}
try:
validate(instance=data, schema=schema)
print("数据有效")
except ValidationError as e:
print(f"验证失败:{e}")
JSONPath 查询
from jsonpath_ng import parse
import json
data = {
"users": [
{"name": "张三", "age": 30},
{"name": "李四", "age": 25}
]
}
# 查找所有姓名
expr = parse('$.users[].name')
names = [match.value for match in expr.find(data)]
print(names) # ['张三', '李四']
结论
Python 的 json 模块为处理 JSON 数据提供了强大而简单的工具。通过掌握其功能和最佳实践,您可以有效地:
- ✅ 解析和生成 JSON 数据
- ✅ 处理复杂的嵌套结构
- ✅ 自定义序列化行为
- ✅ 优化大文件性能
- ✅ 处理错误和验证数据
关键要点
loads/dumps,对文件使用 load/dumpensure_ascii=False 处理 Unicodeindent 进行可读输出try/except 处理错误通过这些技术,您已准备好在 Python 应用程序中自信地处理 JSON!
相关文章
什么是 JSON?2026 年初学者完整指南
了解 JSON 是什么,它的语法、数据类型和使用场景。全面且对初学者友好的 JavaScript 对象表示法指南。
JavaScript JSON:解析和字符串化数据
JavaScript 中 JSON 的完整指南。学习 JSON.parse()、JSON.stringify()、错误处理和 Web 开发的高级技术。
数据科学中的 JSON:Python 和 Pandas 指南
JSON 在数据科学工作流中的完整指南。学习用 Python、Pandas 处理 JSON 并集成到 ML 管道中。