Python中嵌套自定义类型的JSON序列化与反序列化

2024-02-21 09:51:32 浏览数 (3)

对于经常用python开发得小伙伴来说,Python的JSON序列化和反序列化功能非常方便和实用。JSON(JavaScript Object Notation)其实就是一种轻量级的数据交换格式,易于阅读和编写,也易于机器解析和生成。在Python中,可以使用json模块来进行JSON序列化和反序列化操。但是再开发过程中我们还是会经历各种各样得问题。

1、问题背景

在Python开发中,我们经常需要将复杂的数据结构序列化为JSON字符串,以便存储或传输数据。然而,当数据结构中包含嵌套的自定义类型时,使用内置的json库进行序列化可能会遇到困难。例如,我们可能需要序列化一个包含多个部门、人员和技能的组织结构。

2、 解决方案

为了解决这个问题,我们可以采用以下步骤:

  1. 定义一个自定义的JSON编码器,以便将自定义类型转换为字典。
  2. 使用json.dump()函数将数据序列化为JSON字符串,并指定自定义编码器。
  3. 定义一个自定义的JSON解码器,以便将字典转换为自定义类型。
  4. 使用json.load()函数将JSON字符串反序列化为数据结构,并指定自定义解码器。

代码例子

以下是一个简单的示例,演示如何使用自定义编码器和解码器来序列化和反序列化一个包含嵌套自定义类型的组织结构:

代码语言:javascript复制
import json
​
class Company(object):
    def __init__(self, company_id):
        self.company_id = company_id
        self.name = ''
        # other 10 attributes with simple type
        ...
        self.departments = [] #list of Dept objects
​
class Dept(object):
    def __init__(self, dept_id):
        self.dept_id = dept_id
        self.name = ''
        # other 10 attributes with simple type
        ...
        self.persons = [] #list of Person objs
​
​
class Person(object):
    def __init__(self, per_id):
        self.per_id = per_id
        self.name = ''
        # other 10 attributes with simple type
        ...
        self.skills = [] #list of Skill objs
​
class Skill(object):
    def __init__(self, skill_id):
        self.skill_id = skill_id
        self.name = ''
        # other 10 attributes with simple type
        ...
        self.foos = [] #list of Foo objs
​
class Foo(object):
    .....
​
def custom_encoder(obj):
    if isinstance(obj, Company):
        return {'company_id': obj.company_id, 'name': obj.name, 'departments': obj.departments}
    elif isinstance(obj, Dept):
        return {'dept_id': obj.dept_id, 'name': obj.name, 'persons': obj.persons}
    elif isinstance(obj, Person):
        return {'per_id': obj.per_id, 'name': obj.name, 'skills': obj.skills}
    elif isinstance(obj, Skill):
        return {'skill_id': obj.skill_id, 'name': obj.name, 'foos': obj.foos}
    elif isinstance(obj, Foo):
        return {'foo_id': obj.foo_id, 'name': obj.name}
    else:
        return obj
​
def custom_decoder(obj):
    if 'company_id' in obj:
        return Company(obj['company_id'])
    elif 'dept_id' in obj:
        return Dept(obj['dept_id'])
    elif 'per_id' in obj:
        return Person(obj['per_id'])
    elif 'skill_id' in obj:
        return Skill(obj['skill_id'])
    elif 'foo_id' in obj:
        return Foo(obj['foo_id'])
    else:
        return obj
​
# 序列化
company_obj = Company(1)
json_string = json.dumps(company_obj, default=custom_encoder, sort_keys=True, indent=4)
​
# 反序列化
company_obj = json.loads(json_string, object_hook=custom_decoder)

其实通过上面得了解知道,用上面得方法可以非常轻松的将复杂的数据结构序列化为JSON字符串,并在需要时将其反序列化为原始数据结构。对于开发的小伙伴来说非常的友好,这也就是我们再开发中经常需要使用的原因。如果各位还有不懂得问题记得评论区留言讨论。

1 人点赞