位置: 文档库 > Python > 如何使用python读写json文件

如何使用python读写json文件

尽人皆知 上传于 2020-02-29 11:48

《如何使用Python读写JSON文件》

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,因其易读性、结构化和跨语言支持,成为现代软件开发中最常用的数据格式之一。Python通过内置的json模块提供了对JSON文件的完整支持,开发者可以轻松实现Python对象与JSON数据的相互转换。本文将系统讲解如何使用Python读写JSON文件,涵盖基础操作、高级技巧以及常见问题的解决方案。

一、JSON与Python数据类型的映射关系

在开始操作前,理解JSON与Python数据类型之间的对应关系至关重要。JSON支持的数据类型包括:

  • 对象(Object):对应Python的字典(dict)
  • 数组(Array):对应Python的列表(list)
  • 字符串(String):对应Python的字符串(str)
  • 数字(Number):对应Python的整数(int)或浮点数(float)
  • 布尔值(true/false):对应Python的True/False
  • 空值(null):对应Python的None

这种映射关系是Python处理JSON数据的基础。例如,以下JSON对象:

{
  "name": "Alice",
  "age": 30,
  "is_student": false,
  "courses": ["Math", "Science"],
  "address": null
}

可以完美转换为Python字典:

{
  "name": "Alice",
  "age": 30,
  "is_student": False,
  "courses": ["Math", "Science"],
  "address": None
}

二、读取JSON文件

读取JSON文件的核心步骤是:打开文件→读取内容→解析为Python对象。Python的json模块提供了load()方法来实现这一过程。

1. 基本读取方法

假设有一个名为data.json的文件,内容如下:

{
  "employees": [
    {
      "id": 1,
      "name": "John Doe",
      "department": "IT"
    },
    {
      "id": 2,
      "name": "Jane Smith",
      "department": "HR"
    }
  ]
}

读取该文件的代码如下:

import json

with open('data.json', 'r', encoding='utf-8') as file:
    data = json.load(file)

print(type(data))  # 输出: 
print(data['employees'][0]['name'])  # 输出: John Doe

关键点说明:

  • with语句确保文件正确关闭
  • 'r'模式表示读取
  • encoding='utf-8'指定编码格式,避免中文乱码
  • json.load()直接将文件内容解析为Python对象

2. 处理JSON字符串

如果数据是以字符串形式存在,可以使用json.loads()方法:

import json

json_string = '{"name": "Bob", "age": 25}'
python_dict = json.loads(json_string)

print(python_dict['name'])  # 输出: Bob

3. 错误处理

JSON解析可能因格式错误而失败,建议使用try-except块捕获异常:

import json

invalid_json = '{"name": "Alice", "age": }'  # 缺少值的错误JSON

try:
    data = json.loads(invalid_json)
except json.JSONDecodeError as e:
    print(f"JSON解析错误: {e}")
    # 输出: JSON解析错误: Expecting value: line 1 column 21 (char 20)

三、写入JSON文件

将Python对象写入JSON文件的过程与读取相反:创建Python对象→转换为JSON字符串→写入文件。主要使用json.dump()json.dumps()方法。

1. 基本写入方法

以下示例演示如何将Python字典写入JSON文件:

import json

data = {
    "product": "Laptop",
    "price": 999.99,
    "in_stock": True,
    "specs": {
        "CPU": "i7",
        "RAM": "16GB"
    }
}

with open('product.json', 'w', encoding='utf-8') as file:
    json.dump(data, file, indent=4)  # indent参数用于美化输出

生成的product.json文件内容:

{
    "product": "Laptop",
    "price": 999.99,
    "in_stock": true,
    "specs": {
        "CPU": "i7",
        "RAM": "16GB"
    }
}

2. 格式化输出

json.dump()json.dumps()都支持以下格式化参数:

  • indent:指定缩进空格数,使输出更易读
  • sort_keys:按字母顺序排序键
  • ensure_ascii:设为False可保留非ASCII字符(如中文)

示例:

import json

data = {
    "城市": "北京",
    "人口": 2171
}

json_string = json.dumps(data, indent=2, ensure_ascii=False, sort_keys=True)
print(json_string)

输出:

{
  "人口": 2171,
  "城市": "北京"
}

3. 处理JSON字符串

使用json.dumps()将Python对象转换为JSON字符串:

import json

person = {
    "name": "Alice",
    "age": 30,
    "hobbies": ["reading", "swimming"]
}

json_str = json.dumps(person)
print(json_str)  # 输出: {"name": "Alice", "age": 30, "hobbies": ["reading", "swimming"]}

四、高级应用技巧

1. 自定义对象编码

默认情况下,Python的自定义对象无法直接转换为JSON。可以通过实现default参数或继承json.JSONEncoder类来解决。

方法一:使用default参数

import json
from datetime import datetime

def custom_encoder(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()
    raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable")

data = {
    "event": "Conference",
    "date": datetime.now()
}

json_str = json.dumps(data, default=custom_encoder)
print(json_str)

方法二:继承JSONEncoder

import json
from datetime import datetime

class CustomEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.isoformat()
        return super().default(obj)

data = {
    "event": "Workshop",
    "date": datetime.now()
}

json_str = json.dumps(data, cls=CustomEncoder)
print(json_str)

2. 处理大数据量

当处理大型JSON文件时,逐行读取或使用生成器可以提高效率。对于JSON Lines格式(每行一个JSON对象),可以这样处理:

import json

def read_json_lines(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        for line in file:
            yield json.loads(line.strip())

for item in read_json_lines('large_data.jsonl'):
    print(item['id'])  # 假设每个对象都有id字段

3. JSON Schema验证

使用第三方库如jsonschema可以验证JSON数据是否符合预期结构:

import json
from jsonschema import validate

schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "age": {"type": "number", "minimum": 0}
    },
    "required": ["name"]
}

data = {"name": "Alice", "age": 30}

try:
    validate(instance=data, schema=schema)
    print("数据验证通过")
except Exception as e:
    print(f"验证错误: {e}")

五、常见问题解决方案

1. 中文编码问题

问题表现:中文显示为Unicode转义序列(如\u4e2d\u6587)

解决方案:

# 写入时
json.dump(data, file, ensure_ascii=False, indent=2)

# 读取时无需特殊处理,Python会自动解码

2. 日期时间处理

问题:datetime对象无法直接序列化

解决方案:

# 方法1:转换为字符串
data = {
    "created_at": datetime.now().isoformat()
}

# 方法2:使用自定义编码器(见高级技巧部分)

3. 大数字精度丢失

问题:JSON默认将所有数字视为浮点数,可能导致大整数精度丢失

解决方案:

import json
from decimal import Decimal

data = {
    "big_number": Decimal("12345678901234567890")
}

# 需要自定义编码器将Decimal转为字符串
def decimal_encoder(obj):
    if isinstance(obj, Decimal):
        return str(obj)
    raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable")

json_str = json.dumps(data, default=decimal_encoder)
print(json_str)

4. 性能优化

对于超大JSON文件,考虑使用orjson等第三方库,它们提供更快的序列化/反序列化速度:

import orjson

data = {"key": "value"}
json_bytes = orjson.dumps(data)  # 返回bytes而非str
json_str = json_bytes.decode('utf-8')

六、最佳实践总结

  1. 始终使用with语句处理文件,确保资源正确释放
  2. 明确指定文件编码(推荐utf-8)
  3. 对用户提供的JSON数据进行严格验证
  4. 生产环境中添加适当的错误处理
  5. 考虑使用indent参数提高可读性(开发环境)
  6. 对于性能敏感场景,评估第三方库如orjsonujson

关键词

Python、JSON、文件读写、序列化、反序列化、json模块、数据交换、JSONDecodeError、自定义编码、JSON Schema、性能优化

简介

本文详细介绍了Python中处理JSON文件的方法,包括基础读写操作、高级技巧如自定义对象编码和大数据处理,以及常见问题的解决方案。通过实际代码示例,读者可以掌握从简单文件操作到复杂数据验证的全流程技能,适用于Web开发、数据分析和API交互等多种场景。