JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,Python通过json模块提供了对JSON的支持。下面详细介绍JSON在Python中的使用方法。
1. 基本导入
首先需要导入json模块:
import json
2. JSON编码(Python对象 → JSON字符串)
基本编码
data = {
"name": "张三",
"age": 30,
"is_student": False,
"courses": ["数学", "英语", "计算机"],
"address": {
"city": "北京",
"street": "中关村"
}
}
json_str = json.dumps(data)
print(json_str)
# 输出: {"name": "\u5f20\u4e09", "age": 30, "is_student": false, "courses": ["\u6570\u5b66", "\u82f1\u8bed", "\u8ba1\u7b97\u673a"], "address": {"city": "\u5317\u4eac", "street": "\u4e2d\u5173\u6751"}}
编码选项
json.dumps()方法提供了一些有用的参数:
# 缩进和格式化
json_str_pretty = json.dumps(data, indent=4, ensure_ascii=False)
print(json_str_pretty)
"""
{
"name": "张三",
"age": 30,
"is_student": false,
"courses": [
"数学",
"英语",
"计算机"
],
"address": {
"city": "北京",
"street": "中关村"
}
}
"""
# 排序键
json_str_sorted = json.dumps(data, sort_keys=True)
print(json_str_sorted)
# 自定义编码器(处理datetime等特殊对象)
from datetime import datetime
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
data_with_date = {"time": datetime.now()}
json_str_custom = json.dumps(data_with_date, cls=CustomEncoder)
print(json_str_custom)
直接写入文件
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
3. JSON解码(JSON字符串 → Python对象)
基本解码
json_str = '{"name": "李四", "age": 25, "is_student": true}'
data = json.loads(json_str)
print(data) # {'name': '李四', 'age': 25, 'is_student': True}
print(type(data)) # <class 'dict'>
从文件读取
with open('data.json', 'r', encoding='utf-8') as f:
data = json.load(f)
print(data)
解码选项
# 解析数字字符串为float
json_str = '{"price": "12.50"}'
data = json.loads(json_str, parse_float=lambda x: float(x))
print(data) # {'price': 12.5}
# 自定义对象钩子
def object_hook(dct):
if 'name' in dct and 'age' in dct:
return Person(dct['name'], dct['age'])
return dct
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
json_str = '{"name": "王五", "age": 40}'
person = json.loads(json_str, object_hook=object_hook)
print(person.name, person.age) # 王五 40
4. Python与JSON类型对应关系
| Python类型 | JSON类型 |
|---|---|
| dict | object |
| list, tuple | array |
| str | string |
| int, float | number |
| True | true |
| False | false |
| None | null |
5. 处理复杂对象
对于自定义类的对象,需要先转换为可序列化的字典:
class User:
def __init__(self, name, age):
self.name = name
self.age = age
def to_dict(self):
return {'name': self.name, 'age': self.age}
user = User("赵六", 35)
user_json = json.dumps(user.to_dict())
print(user_json) # {"name": "赵六", "age": 35}
# 从JSON恢复对象
def user_from_dict(dct):
return User(dct['name'], dct['age'])
user_obj = json.loads(user_json, object_hook=user_from_dict)
print(user_obj.name, user_obj.age) # 赵六 35
6. 性能考虑
对于大型JSON数据:
- 使用
json.load()和json.dump()直接操作文件,而不是先加载到内存 - 考虑使用
ujson或orjson等第三方库提高性能
7. 常见问题
处理日期时间
from datetime import datetime
def datetime_handler(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Object of type {type(obj)} is not JSON serializable")
data = {'time': datetime.now()}
json_str = json.dumps(data, default=datetime_handler)
print(json_str)
处理特殊字符
# 确保非ASCII字符正确显示
data = {'name': '张三'}
json_str = json.dumps(data, ensure_ascii=False)
print(json_str) # {"name": "张三"}
处理大整数
# JavaScript/JSON无法准确表示大整数
big_num = 2**53 + 1 # JavaScript能表示的最大整数是2^53
data = {'big_num': big_num}
json_str = json.dumps(data)
print(json_str) # {"big_num": 9007199254740993}
通过掌握这些JSON处理方法,你可以轻松地在Python程序中处理各种JSON数据交换需求。