Python如何处理JSON数据?
小伙伴们有没有觉得学习文章很有意思?有意思就对了!今天就给大家带来《Python处理JSON数据的方法详解》,以下内容将会涉及到,若是在学习中对其中部分知识点有疑问,或许看了本文就能帮到你!
Python处理JSON数据主要依赖内置json模块提供的四个核心函数:json.dumps()用于将Python对象编码为JSON字符串;json.loads()用于将JSON字符串解码为Python对象;json.dump()用于将Python对象写入JSON文件;json.load()用于从JSON文件读取数据并解码为Python对象。1. json.dumps()支持参数如indent设置缩进以提升可读性,ensure_ascii=False保留非ASCII字符;2. json.loads()能解析合法JSON字符串,非法格式会抛出json.JSONDecodeError;3. json.dump()和json.load()分别实现文件的写入与读取,推荐使用utf-8编码;4. Python与JSON类型有明确映射,如字典对应对象、列表对应数组等;5. 集合、datetime及自定义类实例等未直接映射的类型需手动转换或自定义序列化逻辑;6. 常见错误包括JSON格式不合法、不可序列化对象及编码不一致等问题,可通过校验、预处理或指定encoding解决;7. 对于复杂结构,可继承json.JSONEncoder实现自定义编码器,或使用object_hook参数实现解码时自动转换为特定对象。掌握这些方法和技巧可高效处理各类JSON数据。
Python处理JSON数据,核心就是利用其内置的json
模块。这个模块提供了将Python对象转换为JSON格式(编码)以及将JSON格式数据转换为Python对象(解码)的工具。你可以轻松地在内存中的字符串和文件之间进行操作。

解决方案
在Python中处理JSON数据,我们主要依赖json
模块提供的四个核心函数:json.dumps()
、json.loads()
、json.dump()
和json.load()
。

编码:从Python对象到JSON格式
当你需要将一个Python对象(比如字典或列表)转换成JSON格式的字符串时,会用到json.dumps()
。这个函数的名字可以理解为“dump string”,把Python数据“倾倒”成字符串。

import json # 一个Python字典 data = { "name": "张三", "age": 30, "isStudent": False, "courses": ["数学", "英语", "计算机"], "address": None } # 使用json.dumps()将字典编码为JSON字符串 json_string = json.dumps(data) print(f"原始JSON字符串:\n{json_string}") # 格式化输出,让JSON更易读 # indent参数可以指定缩进的空格数,ensure_ascii=False可以显示中文 formatted_json_string = json.dumps(data, indent=4, ensure_ascii=False) print(f"\n格式化后的JSON字符串:\n{formatted_json_string}") # 思考一下,如果我有些数据是集合或者自定义对象,dumps会直接报错的,这需要我们额外处理。 # 比如: # try: # json.dumps({"set_data": {1, 2, 3}}) # except TypeError as e: # print(f"\n尝试编码集合时报错: {e}")
indent
参数能让输出的JSON字符串带有缩进,非常适合调试和人类阅读。而ensure_ascii=False
则允许JSON字符串中直接包含非ASCII字符(如中文),而不是将其转义成\uXXXX
的形式,这在很多场景下更直观。
解码:从JSON格式到Python对象
反过来,当你拿到一个JSON格式的字符串,想在Python程序中使用它时,就需要json.loads()
。这个函数可以理解为“load string”,把字符串“加载”成Python数据。
import json # 一个JSON格式的字符串 json_string_to_decode = '{"name": "李四", "age": 25, "city": "北京", "hobbies": ["阅读", "旅行"]}' # 使用json.loads()将JSON字符串解码为Python字典 decoded_data = json.loads(json_string_to_decode) print(f"\n解码后的Python对象:\n{decoded_data}") print(f"姓名: {decoded_data['name']}, 城市: {decoded_data['city']}") # 如果JSON字符串格式不正确,loads会抛出json.JSONDecodeError # try: # json.loads('{"key": "value" broken}') # except json.JSONDecodeError as e: # print(f"\n尝试解码非法JSON时报错: {e}")
文件操作:json.dump()
和json.load()
除了在内存中处理字符串,json
模块还提供了直接与文件交互的函数:json.dump()
和json.load()
。它们的作用与dumps()
和loads()
类似,但直接读写文件。
json.dump(obj, fp, ...)
:将Python对象编码为JSON格式并写入文件对象fp
。
import json data_to_save = { "product": "Laptop", "price": 1200.50, "specs": {"cpu": "i7", "ram": "16GB"}, "available": True } # 写入JSON文件 file_path = "data.json" with open(file_path, "w", encoding="utf-8") as f: json.dump(data_to_save, f, indent=4, ensure_ascii=False) print(f"\n数据已成功写入到 {file_path}") # 检查一下文件内容,你会发现它就是格式化好的JSON。
json.load(fp, ...)
:从文件对象fp
中读取JSON格式数据并解码为Python对象。
import json # 从JSON文件读取数据 file_path = "data.json" try: with open(file_path, "r", encoding="utf-8") as f: loaded_data = json.load(f) print(f"\n从 {file_path} 读取的数据:\n{loaded_data}") print(f"产品: {loaded_data['product']}, 价格: {loaded_data['price']}") except FileNotFoundError: print(f"文件 {file_path} 未找到。") except json.JSONDecodeError as e: print(f"解码JSON文件时出错: {e}")
使用dump
和load
时,务必注意文件的编码,通常推荐使用utf-8
。
Python对象和JSON数据类型之间是如何映射的?
这是一个非常关键的问题,理解它能帮助我们避免很多潜在的坑。json
模块在Python对象和JSON数据类型之间建立了一套明确的映射关系:
- Python
dict
(字典) <-> JSONobject
(对象):这是最常见的映射,Python字典的键(字符串)和值对应JSON对象的键值对。 - Python
list
(列表) 或tuple
(元组) <-> JSONarray
(数组):Python的序列类型会转换为JSON的数组。 - Python
str
(字符串) <-> JSONstring
(字符串):字符串类型直接映射。 - Python
int
(整型) 或float
(浮点型) <-> JSONnumber
(数字):数字类型直接映射。 - Python
True
(布尔真) <-> JSONtrue
(布尔真):布尔值映射。 - Python
False
(布尔假) <-> JSONfalse
(布尔假):布尔值映射。 - Python
None
(空值) <-> JSONnull
(空值):Python的None
对应JSON的null
。
未直接映射的类型和挑战:
有些Python数据类型在JSON中没有直接的对应物,这常常是初学者遇到的第一个“拦路虎”。
set
(集合):JSON没有集合的概念。如果你尝试编码一个包含集合的Python对象,json.dumps()
会抛出TypeError
,因为它不知道如何序列化集合。datetime
(日期时间对象):Python的datetime
对象不能直接序列化。通常的做法是将其转换为ISO 8601格式的字符串(例如"2023-10-27T10:30:00"
)再进行序列化。- 自定义类实例:你创建的自定义类实例,
json
模块默认也无法识别并序列化。
处理这些非标准类型,通常需要我们提供一个自定义的序列化逻辑,或者在编码前手动将它们转换成可序列化的类型(比如字符串)。比如,一个datetime
对象,你可以先str(my_datetime_obj)
,然后再dumps
。
处理JSON数据时常见的错误和挑战有哪些?
在实际开发中,处理JSON数据远不止调用几个函数那么简单,总会遇到各种意想不到的问题。
json.JSONDecodeError
:JSON格式错误 这是最常见的问题,意味着你尝试解码的字符串不是一个合法的JSON格式。可能是少了一个括号、多了一个逗号、使用了单引号而不是双引号、或者键没有用双引号括起来等等。# 错误示例:键没有用双引号 {name: "Alice"} # 错误示例:多余的逗号 {"a": 1, "b": 2,}
遇到这种错误,第一步就是仔细检查你的JSON字符串,或者使用在线JSON校验工具来定位问题。
TypeError
:不可序列化的对象 当你尝试使用json.dumps()
编码一个Python对象时,如果该对象包含json
模块无法直接处理的数据类型(比如set
、datetime
对象、自定义类的实例等),就会抛出TypeError
。import json import datetime data_with_unserializable = { "name": "Test", "timestamp": datetime.datetime.now(), # datetime对象 "items": {1, 2, 3} # 集合 } # try: # json.dumps(data_with_unserializable) # except TypeError as e: # print(f"\n编码时遇到TypeError: {e}")
解决办法是,要么在编码前将这些对象转换为JSON可识别的类型(如将
datetime
转为字符串),要么提供一个自定义的JSON编码器。字符编码问题 虽然JSON规范要求使用UTF-8编码,但在实际文件读写或网络传输中,仍然可能遇到编码不一致的问题。例如,一个JSON文件是用GBK编码保存的,而你尝试用默认的UTF-8去读取,就会导致
UnicodeDecodeError
。 解决方法是在open()
函数中明确指定encoding='utf-8'
(或其他正确的编码)。处理大型JSON文件
json.load()
和json.loads()
会将整个JSON数据加载到内存中进行处理。如果JSON文件非常大(比如几百MB甚至GB),这可能会导致内存溢出。 对于这类问题,你可能需要考虑流式解析(streaming parsing)或者使用专门处理大型JSON的库(例如ijson
),它们可以逐块解析,避免一次性加载全部数据。不过,对于大多数日常应用,内置json
模块足够用了。数据结构不确定性或缺失键 从外部API获取的JSON数据,其结构可能并不总是完全一致。某些键可能缺失,或者值的类型与预期不符。 在访问字典中的键时,最好使用
dict.get()
方法并提供一个默认值,而不是直接使用data['key']
,这样可以避免KeyError
。data = {"name": "Bob"} # print(data['age']) # 会报错 print(data.get('age', '未知年龄')) # 更安全
更进一步,如果数据结构复杂且多变,你可能需要进行数据验证,例如使用
jsonschema
库来根据预定义的JSON Schema进行校验。
如何处理非标准或复杂JSON结构?
当遇到json
模块默认无法处理的Python对象,或者需要将JSON数据解析成特定的Python对象时,我们就需要一些高级技巧。
自定义JSON编码器 (json.JSONEncoder
)
这是处理不可序列化对象的首选方法。你可以继承json.JSONEncoder
,重写它的default()
方法来定义如何处理那些默认无法序列化的类型。
import json import datetime class CustomJSONEncoder(json.JSONEncoder): def default(self, obj): # 如果是datetime对象,转换为ISO格式字符串 if isinstance(obj, datetime.datetime): return obj.isoformat() # 如果是集合,转换为列表 if isinstance(obj, set): return list(obj) # 其他类型,交给基类的default方法处理,如果仍然无法处理会抛出TypeError return json.JSONEncoder.default(self, obj) data_with_custom_types = { "event_name": "Meeting", "start_time": datetime.datetime(2023, 10, 27, 14, 0, 0), "participants_ids": {101, 102, 103}, "location": "Conference Room A" } # 使用自定义编码器进行序列化 encoded_json = json.dumps(data_with_custom_types, indent=4, cls=CustomJSONEncoder, ensure_ascii=False) print(f"\n使用自定义编码器编码后的JSON:\n{encoded_json}")
通过这种方式,你可以优雅地处理datetime
、Decimal
、甚至是你自己的自定义类实例(例如,让自定义类的实例返回一个字典表示)。
自定义JSON解码器 (object_hook
)
在解码时,你可能希望将JSON中的特定字典结构直接转换为Python的自定义对象,而不是普通的字典。json.loads()
和json.load()
都支持一个object_hook
参数,它是一个函数,会在JSON对象(字典)被解码后调用。
import json class User: def __init__(self, user_id, name, email): self.user_id = user_id self.name = name self.email = email def __repr__(self): return f"User(id={self.user_id}, name='{self.name}', email='{self.email}')" def user_object_hook(dct): # 如果字典包含'__type__'键且值为'User',则将其转换为User对象 if '__type__' in dct and dct['__type__'] == 'User': return User(dct['user_id'], dct['name'], dct['email']) return dct # 否则返回原始字典 json_data_with_user = '{"__type__": "User", "user_id": 1, "name": "Alice", "email": "alice@example.com", "other_field": "value"}' # 使用object_hook进行解码 decoded_object = json.loads(json_data_with_user, object_hook=user_object_hook) print(f"\n使用object_hook解码后的对象:\n{decoded_object}") print(f"对象类型: {type(decoded_object)}")
这种方法非常适合将扁平的JSON数据结构“复活”成具有特定行为和属性的Python对象。当然,这要求你的JSON数据中包含一些元信息(比如示例中的__type__
),以便object_hook
函数识别并进行转换。
总的来说,Python的json
模块功能强大且灵活。掌握了基本的编码解码,并学会处理常见的错误和自定义序列化/反序列化逻辑,你就能游刃有余地处理各种JSON数据了。在遇到问题时,错误信息通常会给你很好的指引。
终于介绍完啦!小伙伴们,这篇关于《Python如何处理JSON数据?》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布文章相关知识,快来关注吧!

- 上一篇
- PHPMyAdmin数据库监控技巧

- 下一篇
- 电脑频繁关机原因解析及解决方法
-
- 文章 · python教程 | 13分钟前 |
- Python中True表示真,用于条件判断
- 267浏览 收藏
-
- 文章 · python教程 | 16分钟前 |
- Python中log函数使用详解
- 317浏览 收藏
-
- 文章 · python教程 | 20分钟前 | Python spark kafka 流数据处理 StructuredStreaming
- Python流处理:Kafka与Spark实战教程
- 435浏览 收藏
-
- 文章 · python教程 | 32分钟前 |
- Python游戏开发入门:Pygame教程详解
- 272浏览 收藏
-
- 文章 · python教程 | 34分钟前 |
- Pythonrarfile模块使用教程详解
- 341浏览 收藏
-
- 文章 · python教程 | 44分钟前 |
- Python中id的作用与对象标识解析
- 488浏览 收藏
-
- 文章 · python教程 | 52分钟前 |
- Python字符串高效操作技巧分享
- 490浏览 收藏
-
- 文章 · python教程 | 56分钟前 |
- Python处理PDF技巧:PyPDF2功能详解
- 278浏览 收藏
-
- 文章 · python教程 | 59分钟前 |
- Python中ord函数的作用详解
- 419浏览 收藏
-
- 文章 · python教程 | 1小时前 |
- Python类继承深度解析与面向对象进阶教程
- 357浏览 收藏
-
- 文章 · python教程 | 1小时前 | csv JSON
- Python轻松转换JSONCSVExcel教程
- 395浏览 收藏
-
- 文章 · python教程 | 1小时前 |
- PyCharm切换英文界面教程
- 149浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 509次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 边界AI平台
- 探索AI边界平台,领先的智能AI对话、写作与画图生成工具。高效便捷,满足多样化需求。立即体验!
- 360次使用
-
- 免费AI认证证书
- 科大讯飞AI大学堂推出免费大模型工程师认证,助力您掌握AI技能,提升职场竞争力。体系化学习,实战项目,权威认证,助您成为企业级大模型应用人才。
- 377次使用
-
- 茅茅虫AIGC检测
- 茅茅虫AIGC检测,湖南茅茅虫科技有限公司倾力打造,运用NLP技术精准识别AI生成文本,提供论文、专著等学术文本的AIGC检测服务。支持多种格式,生成可视化报告,保障您的学术诚信和内容质量。
- 517次使用
-
- 赛林匹克平台(Challympics)
- 探索赛林匹克平台Challympics,一个聚焦人工智能、算力算法、量子计算等前沿技术的赛事聚合平台。连接产学研用,助力科技创新与产业升级。
- 624次使用
-
- 笔格AIPPT
- SEO 笔格AIPPT是135编辑器推出的AI智能PPT制作平台,依托DeepSeek大模型,实现智能大纲生成、一键PPT生成、AI文字优化、图像生成等功能。免费试用,提升PPT制作效率,适用于商务演示、教育培训等多种场景。
- 527次使用
-
- Flask框架安装技巧:让你的开发更高效
- 2024-01-03 501浏览
-
- Django框架中的并发处理技巧
- 2024-01-22 501浏览
-
- 提升Python包下载速度的方法——正确配置pip的国内源
- 2024-01-17 501浏览
-
- Python与C++:哪个编程语言更适合初学者?
- 2024-03-25 501浏览
-
- 品牌建设技巧
- 2024-04-06 501浏览