如何用Python转换JSON数据:从基础到实践的全面指南
在数据驱动的时代,JSON(JavaScript Object Notation)因其轻量级、易读、易解析的特性,已成为跨平台数据交换的主流格式之一,无论是Web API的响应、配置文件存储,还是数据序列化场景,JSON都无处不在,Python作为一门简洁强大的编程语言,提供了内置的json
模块,让JSON数据的转换变得简单高效,本文将从基础概念出发,详细介绍如何用Python进行JSON数据的转换,包括基本操作、高级技巧及常见问题解决。
JSON与Python的数据类型映射
在开始转换前,需要明确JSON数据与Python数据类型的对应关系,这是正确解析和生成JSON的基础:
JSON数据类型 | Python数据类型 |
---|---|
object(对象) | dict(字典) |
array(数组) | list(列表) |
string(字符串) | str(字符串) |
number(数字,整数或浮点数) | int/float(整数/浮点数) |
true/false | True/False(布尔值) |
null | None(空值) |
核心方法:json
模块的四大功能
Python的json
模块(无需安装,内置标准库)提供了四个核心函数,覆盖JSON的“序列化”(Python对象→JSON字符串)和“反序列化”(JSON字符串→Python对象)需求:
json.dumps()
:将Python对象序列化为JSON字符串
作用:将Python的dict
、list
等对象转换为JSON格式的字符串,常用于数据传输或存储前的格式化。
语法:
json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
常用参数:
indent
:指定缩进空格数,使JSON字符串格式化(易读,但会增加字符串长度)。ensure_ascii
:默认为True
,非ASCII字符会转义为\uXXXX
;设为False
可保留原字符(如中文)。sort_keys
:默认为False
;设为True
会按字典键的字母顺序排序输出。
示例:
import json python_dict = { "name": "张三", "age": 25, "is_student": False, "courses": ["数学", "Python"], "info": None } # 序列化为JSON字符串(默认紧凑格式) json_str = json.dumps(python_dict) print("紧凑格式:", json_str) # 输出: {"name": "\u5f20\u4e09", "age": 25, "is_student": false, "courses": ["\u6570\u5b66", "Python"], "info": null} # 序列化为格式化JSON(保留中文,排序键) json_str_formatted = json.dumps( python_dict, indent=4, ensure_ascii=False, sort_keys=True ) print("格式化输出:") print(json_str_formatted) # 输出(缩进4空格,键排序): # { # "age": 25, # "courses": [ # "数学", # "Python" # ], # "info": null, # "is_student": false, # "name": "张三" # }
json.loads()
:将JSON字符串反序列化为Python对象
作用:将JSON格式的字符串解析为Python的dict
、list
等对象,常用于处理API响应或读取JSON文件。
语法:
json.loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
常用参数:
object_hook
:指定一个函数,用于解析JSON对象(dict
)时对结果进行自定义处理(如转换特定字段类型)。
示例:
import json json_str = '{"name": "李四", "age": 30, "hobbies": ["阅读", "旅行"]}' # 反序列化为Python字典 python_dict = json.loads(json_str) print("反序列化结果:", python_dict) print("类型:", type(python_dict)) # 输出: # 反序列化结果: {'name': '李四', 'age': 30, 'hobbies': ['阅读', '旅行']} # 类型: <class 'dict'> # 通过object_hook处理特定字段(如将"age"转为字符串) def custom_decoder(obj): if "age" in obj and isinstance(obj["age"], int): obj["age"] = str(obj["age"]) + "岁" return obj python_dict_custom = json.loads(json_str, object_hook=custom_decoder) print("自定义处理结果:", python_dict_custom) # 输出: {'name': '李四', 'age': '30岁', 'hobbies': ['阅读', '旅行']}
json.dump()
:将Python对象序列化为JSON文件
作用:直接将Python对象写入文件(以JSON格式),避免手动调用dumps()
后再写入文件,适合处理大文件或需要持久化存储的场景。
语法:
json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
参数说明:
fp
:文件对象(需以写入模式打开,如open("file.json", "w", encoding="utf-8")
)。- 其他参数与
dumps()
一致(如indent
、ensure_ascii
)。
示例:
import json data = { "city": "北京", "population": 21540000, "landmarks": ["故宫", "长城", "天安门"] } # 写入JSON文件(格式化,保留中文) with open("beijing.json", "w", encoding="utf-8") as f: json.dump(data, f, indent=4, ensure_ascii=False) print("数据已写入beijing.json") # { # "city": "北京", # "population": 21540000, # "landmarks": [ # "故宫", # "长城", # "天安门" # ] # }
json.load()
:从JSON文件中读取数据并反序列化为Python对象
作用:直接从文件读取JSON内容并解析为Python对象,适合从文件中加载JSON数据。
语法:
json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
参数说明:
fp
:文件对象(需以读取模式打开,如open("file.json", "r", encoding="utf-8")
)。- 其他参数与
loads()
一致。
示例:
import json # 从文件读取JSON数据 with open("beijing.json", "r", encoding="utf-8") as f: data = json.load(f) print("从文件读取的数据:", data) print("类型:", type(data)) # 输出: # 从文件读取的数据: {'city': '北京', 'population': 21540000, 'landmarks': ['故宫', '长城', '天安门']} # 类型: <class 'dict'>
进阶技巧:处理复杂场景
自定义序列化/反序列化(处理非标准类型)
Python的json
模块默认不支持datetime
、Decimal
等类型的序列化,若需处理这些类型,需通过default
参数(序列化时)或object_hook
(反序列化时)自定义逻辑。
示例:序列化datetime
对象
import json from datetime import datetime def datetime_serializer(obj): if isinstance(obj, datetime): return obj.isoformat() # 转换为ISO格式字符串 raise TypeError(f"Object of type {type(obj)} is not JSON serializable") data = { "time": datetime.now(), "event": "测试" } # 使用default参数处理datetime json_str = json.dumps(data, default=datetime_serializer, ensure_ascii=False) print("序列化datetime:", json_str) # 输出: {"time": "2023-10-01 12:00:00.123456", "event": "测试"}
处理大文件(流式读写)
当JSON文件较大时(如GB级别),直接调用load()
或dump()
可能导致内存溢出,此时可使用ijson
库(需安装:pip install ijson
)进行流式解析或生成。
**示例
还没有评论,来说两句吧...