Python中JSON对象的使用方法

203 阅读3分钟

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类型
dictobject
list, tuplearray
strstring
int, floatnumber
Truetrue
Falsefalse
Nonenull

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()直接操作文件,而不是先加载到内存
  • 考虑使用ujsonorjson等第三方库提高性能

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数据交换需求。