Python如何操作JSON文件?读写与解析

爱谁谁
发布: 2025-08-12 16:08:01
原创
402人浏览过

python操作json文件的核心是使用内置json模块的load、dump、loads、dumps四个方法,1. 读取json文件用json.load()将json数据反序列化为python字典或列表,2. 写入json文件用json.dump()将python数据序列化为json格式并保存,3. 解析json字符串用json.loads()将其转换为python对象,4. 生成json字符串用json.dumps()将python对象序列化为json字符串,所有操作需注意编码设置encoding='utf-8'和ensure_ascii=false以支持中文,同时需处理json与python间的数据类型映射,如dict↔object、list↔array、none↔null,避免set、tuple、datetime等类型直接序列化的错误,可通过自定义jsonencoder或object_hook解决复杂类型转换问题,最终实现文件读写、api通信、配置管理、日志记录等场景下的可靠数据交换。

Python如何操作JSON文件?读写与解析

Python操作JSON文件,核心就是利用其内置的

json
登录后复制
模块进行数据序列化和反序列化。说白了,就是把Python的数据结构(比如字典、列表)转换成JSON格式的字符串,或者把JSON格式的字符串解析回Python的数据结构。无论是文件读写还是内存中的字符串处理,
json
登录后复制
模块都能轻松搞定。

解决方案

Python处理JSON文件,主要围绕

json
登录后复制
模块的四个核心方法展开:
load()
登录后复制
dump()
登录后复制
用于文件操作,
loads()
登录后复制
dumps()
登录后复制
用于字符串操作。

1. 读取JSON文件(反序列化到Python对象)

立即学习Python免费学习笔记(深入)”;

当你有一个

.json
登录后复制
文件,想把它里面的数据读到Python里变成字典或列表,就用
json.load()
登录后复制

import json

file_path = 'data.json' # 假设你有一个名为data.json的文件
# data.json内容示例: {"name": "张三", "age": 30, "isStudent": false, "courses": ["Math", "Physics"]}

try:
    with open(file_path, 'r', encoding='utf-8') as f:
        data = json.load(f)
    print("成功读取文件,数据类型:", type(data))
    print("读取到的数据:", data)
    print("姓名:", data.get('name'))
except FileNotFoundError:
    print(f"错误:文件 '{file_path}' 不存在。")
except json.JSONDecodeError as e:
    print(f"错误:JSON解析失败,文件 '{file_path}' 可能格式不正确。详细信息:{e}")
except Exception as e:
    print(f"发生未知错误:{e}")
登录后复制

这里我习惯用

with open(...)
登录后复制
,因为它能确保文件被正确关闭,避免资源泄露。
encoding='utf-8'
登录后复制
是处理中文等非ASCII字符的关键,避免乱码。

2. 写入JSON文件(序列化Python对象)

如果你有一些Python数据,想保存成JSON格式的文件,就用

json.dump()
登录后复制

import json

my_data = {
    "name": "李四",
    "age": 25,
    "city": "北京",
    "interests": ["coding", "reading", "travel"],
    "is_active": True,
    "null_value": None
}

output_file_path = 'output.json'

try:
    with open(output_file_path, 'w', encoding='utf-8') as f:
        # indent=4 让输出的JSON文件更易读,每个层级缩进4个空格
        # ensure_ascii=False 确保非ASCII字符(如中文)直接写入,而不是转义成\uXXXX
        json.dump(my_data, f, indent=4, ensure_ascii=False)
    print(f"数据已成功写入到 '{output_file_path}'")
except IOError as e:
    print(f"写入文件时发生IO错误:{e}")
except Exception as e:
    print(f"发生未知错误:{e}")
登录后复制

indent
登录后复制
参数非常有用,特别是当你需要人工阅读JSON文件时,它会格式化输出,让结构一目了然。
ensure_ascii=False
登录后复制
是我处理中文数据时的必备选项,不然中文都会变成
\uXXXX
登录后复制
这样的编码,阅读起来很不方便。

3. 从JSON字符串解析(反序列化到Python对象)

有时候数据不是来自文件,而是通过网络请求(比如API接口返回)或者内存中的一个字符串,这时候就需要

json.loads()
登录后复制

import json

json_string = '{"product": "Laptop", "price": 1200.50, "specs": {"cpu": "i7", "ram": "16GB"}}'

try:
    product_info = json.loads(json_string)
    print("从字符串解析到的数据:", product_info)
    print("产品名称:", product_info['product'])
except json.JSONDecodeError as e:
    print(f"错误:JSON字符串解析失败。详细信息:{e}")
登录后复制

4. 将Python对象转换为JSON字符串(序列化)

反过来,如果你想把Python数据转换成JSON格式的字符串,然后可能通过网络发送,或者存到数据库的某个文本字段里,就用

json.dumps()
登录后复制

import json

python_object = {
    "event": "login",
    "user_id": 12345,
    "timestamp": "2023-10-27T10:30:00Z"
}

# 同样可以使用 indent 和 ensure_ascii 参数
json_output_string = json.dumps(python_object, indent=2, ensure_ascii=False)
print("转换后的JSON字符串:")
print(json_output_string)
登录后复制

这四个方法基本覆盖了日常JSON操作的绝大部分场景。掌握它们,你就掌握了Python处理JSON的核心能力。

JSON与Python的数据类型是如何对应转换的?

这是个挺基础但又非常重要的问题,理解了它,你就能更好地预判数据转换后的形态,也能避免一些类型不匹配的坑。说白了,

json
登录后复制
模块在序列化(Python到JSON)和反序列化(JSON到Python)时,有一套固定的映射规则。

  • JSON Object (对象) <-> Python dict (字典):这是最常见的对应关系。JSON的对象是键值对的集合,键必须是字符串。Python的字典也是键值对集合,键可以是任何不可变类型,但序列化为JSON时,非字符串键会被转换为字符串。

    • {"name": "Alice", "age": 30}
      登录后复制
      <->
      {'name': 'Alice', 'age': 30}
      登录后复制
  • JSON Array (数组) <-> Python list (列表):JSON的数组是有序的值的集合。Python的列表也是有序的。

    • ["apple", "banana", "cherry"]
      登录后复制
      <->
      ['apple', 'banana', 'cherry']
      登录后复制
  • JSON String (字符串) <-> Python str (字符串):这个很简单,就是文本。

    • "Hello World"
      登录后复制
      <->
      'Hello World'
      登录后复制
  • JSON Number (数字) <-> Python int / float (整数 / 浮点数):JSON不区分整数和浮点数,统一为Number。Python会根据实际值转换成

    int
    登录后复制
    float
    登录后复制

    • 123
      登录后复制
      <->
      123
      登录后复制
      (int)
    • 3.14
      登录后复制
      <->
      3.14
      登录后复制
      (float)
  • JSON Boolean (布尔值) <-> Python bool (布尔值)

    true
    登录后复制
    对应
    true
    登录后复制
    false
    登录后复制
    对应
    false
    登录后复制

    • true
      登录后复制
      <->
      true
      登录后复制
    • false
      登录后复制
      <->
      false
      登录后复制
  • JSON null (空值) <-> Python None (空值):JSON的

    null
    登录后复制
    对应Python的
    None
    登录后复制

    • null
      登录后复制
      <->
      None
      登录后复制

需要注意的“陷阱”:

  1. 集合(Set):Python的
    set
    登录后复制
    类型是无序且唯一的集合,JSON没有直接对应的类型。如果你尝试序列化一个
    set
    登录后复制
    json.dumps()
    登录后复制
    会抛出
    TypeError
    登录后复制
    • 解决办法:通常在序列化前将其转换为
      list
      登录后复制
      list(my_set)
      登录后复制
  2. 元组(Tuple):Python的
    tuple
    登录后复制
    在序列化时会被转换为JSON Array,也就是Python的
    list
    登录后复制
    。反序列化回来时,JSON Array会变成Python的
    list
    登录后复制
    ,而不是
    tuple
    登录后复制
    。所以,元组的“不可变性”在JSON序列化后就丢失了。
    • ("a", "b")
      登录后复制
      ->
      ["a", "b"]
      登录后复制
      (JSON) ->
      ['a', 'b']
      登录后复制
      (Python)
  3. 日期时间对象(datetime):JSON本身没有内置的日期时间类型。Python的
    datetime
    登录后复制
    对象默认也无法直接序列化。
    • 解决办法:通常将其格式化为ISO 8601字符串(例如
      "2023-10-27T10:30:00Z"
      登录后复制
      ),或者时间戳(整数/浮点数),再进行序列化。反序列化时再手动解析回
      datetime
      登录后复制
      对象。
  4. 自定义类实例:你不能直接把一个自定义类的对象序列化成JSON。
    • 解决办法:需要为
      json.dumps()
      登录后复制
      提供一个自定义的
      default
      登录后复制
      函数,或者让你的类实现一个
      to_json
      登录后复制
      方法,将自身转换为可序列化的字典。

理解这些映射关系,能让你在处理数据时少走很多弯路。在我看来,尤其是

set
登录后复制
datetime
登录后复制
这两个,是初学者最容易踩的坑。

操作JSON文件时,有哪些常见的错误及调试技巧?

在实际开发中,操作JSON文件确实会遇到一些小麻烦,尤其是数据格式不规范的时候。我把我经常碰到的问题和一些调试经验分享给你。

1.

json.JSONDecodeError: Expecting value:
登录后复制
json.JSONDecodeError: Extra data:
登录后复制

  • 原因:这是最常见的错误,意味着你的JSON文件(或字符串)格式不正确。可能是:
    • 缺少逗号、冒号、引号。
    • 使用了单引号而不是双引号(JSON标准要求双引号)。
    • 文件是空的,或者只包含空格。
    • 文件内容不是有效的JSON(比如只是一个普通的文本文件)。
    • JSON字符串后面有多余的、无法解析的内容。
  • 调试技巧
    • 在线JSON校验器:这是我最常用的方法。把报错的JSON内容复制到像JSONLint、JSON Formatter & Validator这样的在线工具里,它们会明确指出错误在哪一行哪一列。
    • 逐行检查:对于小文件,可以肉眼检查。特别注意键值对之间的冒号、元素之间的逗号、字符串的双引号。
    • 打印原始字符串:如果是从文件读取,先尝试把文件内容作为纯字符串打印出来,看看是不是在读取阶段就出了问题(比如文件编码不匹配)。
      # 假设 file_path 导致了 JSONDecodeError
      try:
          with open(file_path, 'r', encoding='utf-8') as f:
              raw_content = f.read()
              print("--- 原始文件内容开始 ---")
              print(raw_content)
              print("--- 原始文件内容结束 ---")
              data = json.loads(raw_content) # 尝试用 loads 解析字符串
      except Exception as e:
          print(f"解析错误:{e}")
      登录后复制

2.

TypeError: Object of type X is not JSON serializable
登录后复制

  • 原因:当你尝试用

    json.dump()
    登录后复制
    json.dumps()
    登录后复制
    序列化Python对象时,如果其中包含了JSON模块不认识的数据类型(比如
    set
    登录后复制
    datetime
    登录后复制
    对象、自定义类的实例等),就会抛出这个错误。

    Find JSON Path Online
    Find JSON Path Online

    Easily find JSON paths within JSON objects using our intuitive Json Path Finder

    Find JSON Path Online 30
    查看详情 Find JSON Path Online
  • 调试技巧

    • 检查数据结构:仔细检查你要序列化的Python数据(字典或列表)中是否有非标准类型。

    • 类型转换:在序列化前,手动将这些不兼容的类型转换为JSON可识别的类型。例如,

      set
      登录后复制
      list
      登录后复制
      datetime
      登录后复制
      转字符串。

    • 自定义序列化器:对于自定义类或复杂类型,可以为

      json.dumps()
      登录后复制
      json.dump()
      登录后复制
      提供一个
      default
      登录后复制
      参数,传入一个函数来处理这些特殊类型。

      import datetime
      class MyEncoder(json.JSONEncoder):
          def default(self, obj):
              if isinstance(obj, datetime.datetime):
                  return obj.isoformat() # 将 datetime 对象转换为 ISO 格式字符串
              if isinstance(obj, set):
                  return list(obj) # 将 set 转换为 list
              return json.JSONEncoder.default(self, obj)
      
      data_with_unserializable = {
          "name": "测试",
          "timestamp": datetime.datetime.now(),
          "tags": {"python", "json"}
      }
      # 使用自定义编码器
      json_str = json.dumps(data_with_unserializable, cls=MyEncoder, indent=2, ensure_ascii=False)
      print(json_str)
      登录后复制

      这种方式非常灵活,能让你优雅地处理各种复杂数据类型。

3.

FileNotFoundError
登录后复制

  • 原因:文件路径不正确,或者文件根本不存在。
  • 调试技巧
    • 检查路径:确保文件路径是正确的,是绝对路径还是相对路径?相对路径是相对于你运行Python脚本的目录。
    • 打印路径:在
      open()
      登录后复制
      之前,
      print(file_path)
      登录后复制
      ,确认路径是否符合预期。
    • 文件存在性检查:在尝试打开文件前,可以使用
      os.path.exists(file_path)
      登录后复制
      来检查文件是否存在。
      import os
      if not os.path.exists(file_path):
          print(f"错误:文件 '{file_path}' 不存在,请检查路径。")
      else:
          # 尝试打开文件
          pass
      登录后复制

4. 编码问题(乱码)

  • 原因:读取或写入文件时,指定的编码与文件实际编码不符。常见于处理包含中文的JSON文件。
  • 调试技巧
    • 统一使用UTF-8:在
      open()
      登录后复制
      函数中始终明确指定
      encoding='utf-8'
      登录后复制
      ,无论是读还是写。这是处理多语言的最佳实践。
    • ensure_ascii=False
      登录后复制
      :在
      json.dump()
      登录后复制
      json.dumps()
      登录后复制
      时,如果输出包含非ASCII字符(如中文),务必设置
      ensure_ascii=False
      登录后复制
    • 检查文件本身编码:如果问题依旧,尝试用文本编辑器(如VS Code、Notepad++)打开JSON文件,查看其编码格式。有时候文件本身就不是UTF-8,需要先转换。

总的来说,处理JSON错误,核心就是“看报错信息,定位问题,然后用最直接的方式验证”。多用

try-except
登录后复制
块,能让你的程序在面对异常数据时更健壮。

除了基本的读写,JSON在Web开发和数据交换中还有哪些高级应用?

JSON的魅力远不止文件读写那么简单,它已经成为现代Web开发和各种系统间数据交换的“通用语言”。在我看来,它的高级应用主要体现在以下几个方面:

1. API接口的数据载体

这是JSON最核心、也最普遍的应用场景。无论是前端(Web、移动App)与后端服务器通信,还是后端服务之间(微服务架构)的通信,JSON都是首选的数据格式。

  • RESTful API:客户端发送HTTP请求(GET, POST, PUT, DELETE),请求体(Request Body)和响应体(Response Body)通常都是JSON格式。
    • 例如,用户登录时,前端发送一个包含用户名和密码的JSON对象到后端。后端验证后,返回一个包含用户信息的JSON对象。
  • 优点:轻量、易读、易解析,跨语言兼容性极佳。几乎所有编程语言都有成熟的JSON解析库。

2. 配置文件格式

很多应用程序、服务甚至前端项目的配置,都喜欢用JSON文件。

  • 优点:结构清晰,支持嵌套,易于程序读取和修改。相比于INI或XML,JSON更简洁,且能直接映射到Python的字典结构,处理起来非常方便。
  • 示例
    {
      "database": {
        "host": "localhost",
        "port": 5432,
        "user": "admin",
        "password": "secure_password"
      },
      "logging": {
        "level": "INFO",
        "file": "/var/log/app.log"
      },
      "features": ["dark_mode", "notifications"]
    }
    登录后复制

    程序启动时加载这个JSON文件,就能获取所有配置信息。

3. 数据持久化与缓存

当需要将Python对象存储起来,但又不想用复杂的数据库,或者需要快速读写时,JSON是个不错的选择。

  • 简单数据库替代:对于小型应用或临时数据,可以将数据序列化成JSON字符串存储在文本文件中,作为一种简单的“文件数据库”。
  • 缓存:将Python对象序列化为JSON字符串,存储在Redis、Memcached等键值存储系统中作为缓存。下次请求时直接从缓存读取,避免重复计算或数据库查询。

4. 日志记录与数据分析

将程序的运行日志、事件数据以JSON格式记录,方便后续的日志分析和数据挖掘。

  • 结构化日志:传统的日志是纯文本,解析困难。JSON日志则能清晰地记录事件类型、时间戳、用户ID、操作详情等结构化信息,便于ELK Stack (Elasticsearch, Logstash, Kibana) 等工具进行索引、搜索和可视化。
    {"timestamp": "2023-10-27T11:00:00Z", "level": "INFO", "message": "User logged in", "user_id": 123, "ip_address": "192.168.1.1"}
    {"timestamp": "2023-10-27T11:00:05Z", "level": "ERROR", "message": "Database connection failed", "error_code": 500}
    登录后复制

5. 消息队列中的消息体

在RabbitMQ、Kafka等消息队列系统中,生产者发送的消息和消费者接收的消息,通常也是JSON格式的字符串。

  • 优点:不同服务(可能由不同语言编写)之间可以通过JSON作为统一的消息格式进行通信,解耦了服务间的依赖。

6. 自定义序列化与反序列化

前面提到了

default
登录后复制
参数和
object_hook
登录后复制
参数,它们允许你处理JSON模块默认不支持的Python类型,或者在反序列化时将JSON数据转换为特定的Python对象。

  • default
    登录后复制
    参数:在序列化时,处理那些非标准Python类型(如
    datetime
    登录后复制
    Decimal
    登录后复制
    、自定义类实例),将它们转换为可JSON化的形式。

  • object_hook
    登录后复制
    参数:在反序列化时,在Python字典被创建后,你可以通过这个钩子函数对字典进行后处理,例如,将特定的字典转换为自定义类的实例。

    # 假设有一个表示坐标的类
    class Point:
        def __init__(self, x, y):
            self.x = x
            self.y = y
    
        def __repr__(self):
            return f"Point(x={self.x}, y={self.y})"
    
    # 自定义 object_hook
    def as_point(dct):
        if 'x' in dct and 'y' in dct:
            return Point(dct['x'], dct['y'])
        return dct
    
    json_str_point = '{"x": 10, "y": 20}'
    point_obj = json.loads(json_str_point, object_hook=as_point)
    print(point_obj) # 输出: Point(x=10, y=20)
    print(type(point_obj)) # 输出: <class '__main__.Point'>
    登录后复制

    这种高级用法在处理复杂数据结构,或者需要将JSON数据映射到特定领域模型时非常有用。

总而言之,JSON的“高级”之处在于它作为一种简单而强大的数据交换格式,极大地简化了不同系统、不同语言之间的数据交互,是现代软件架构中不可或缺的一部分。

以上就是Python如何操作JSON文件?读写与解析的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号