如何在Python中将JSON转换为类对象?类似Java ObjectMapper(含一对多示例)
嘿,这个需求太常见了!在Python里想要实现类似Java Jackson框架ObjectMapper的功能——把JSON数据转换成自定义的类对象,尤其是处理像你说的Course(父)和Books(子)这种一对多的嵌套结构,其实有两种非常实用的方式,我结合你的示例数据给你一步步演示。
方法一:用标准库dataclasses + json
Python 3.7+自带的dataclasses可以轻松定义数据类,配合json模块,再写个简单的转换函数就能搞定嵌套结构的解析,完全不用装第三方库。
步骤1:定义数据类
首先咱们先把Course和Book这两个实体类用@dataclass装饰器定义出来,注意Course里的books字段要标注为List[Book],明确是Book对象的列表:
from dataclasses import dataclass from typing import List import json @dataclass class Book: id: int name: str @dataclass class Course: id: int name: str books: List[Book]
步骤2:编写转换函数
因为json.loads()只会把JSON转成字典和列表,所以咱们需要一个递归函数,把嵌套的字典转换成对应的类实例:
def from_dict(data: dict, cls): # 如果目标类是dataclass,就解析字段 if hasattr(cls, '__dataclass_fields__'): field_types = {f.name: f.type for f in cls.__dataclass_fields__.values()} kwargs = {} for field_name, field_type in field_types.items(): # 递归处理嵌套的字典类型 if isinstance(data[field_name], dict): kwargs[field_name] = from_dict(data[field_name], field_type) # 处理列表类型,取出列表的元素类型再递归转换 elif isinstance(data[field_name], list) and hasattr(field_type, '__origin__') and field_type.__origin__ is list: item_type = field_type.__args__[0] kwargs[field_name] = [from_dict(item, item_type) for item in data[field_name]] else: kwargs[field_name] = data[field_name] return cls(**kwargs) return data
步骤3:测试转换
现在用你给的JSON数据来测试:
# 你的示例JSON数据 json_str = '{"id": 1, "name": "Course 1", "books": [{"id": 1, "name": "Book 1"}, {"id": 2, "name": "Book 2"}]}' # 先转成字典 json_dict = json.loads(json_str) # 转成Course对象 course_obj = from_dict(json_dict, Course) # 验证结果 print(course_obj) # 输出:Course(id=1, name='Course 1', books=[Book(id=1, name='Book 1'), Book(id=2, name='Book 2')]) print(course_obj.books[0].name) # 输出:Book 1
方法二:使用Pydantic(更简洁高效)
如果你的场景更复杂,比如需要数据验证、自动类型转换,那Pydantic绝对是更好的选择——它就像Python版的Jackson,开箱即用,不用自己写转换函数,还自带很多实用功能。
步骤1:安装Pydantic
先通过pip安装:
pip install pydantic
步骤2:定义模型类
只需要让类继承自pydantic.BaseModel,剩下的类型解析、嵌套转换全交给Pydantic处理:
from pydantic import BaseModel from typing import List import json class Book(BaseModel): id: int name: str class Course(BaseModel): id: int name: str books: List[Book]
步骤3:一键转换
Pydantic提供了多种解析方法,比如parse_raw()直接解析JSON字符串,或者用**解包字典:
json_str = '{"id": 1, "name": "Course 1", "books": [{"id": 1, "name": "Book 1"}, {"id": 2, "name": "Book 2"}]}' # 方法1:直接解析JSON字符串 course_obj = Course.parse_raw(json_str) # 方法2:先转字典再解析 json_dict = json.loads(json_str) course_obj = Course(**json_dict) # 验证结果 print(course_obj) # 输出:id=1 name='Course 1' books=[Book(id=1, name='Book 1'), Book(id=2, name='Book 2')] print(course_obj.books[1].id) # 输出:2
另外,Pydantic还支持把类对象转回JSON(course_obj.json()),如果JSON数据不符合类型定义还会自动抛出错误,非常适合生产环境使用。
内容的提问来源于stack exchange,提问作者Anil Kumar

