MST

星途 面试题库

面试题:Python中json.dumps序列化数据高级难度题

有一个自定义的Python类,类中有一些属性,如class MyClass: def __init__(self): self.attr1 = 'value1'; self.attr2 = 42。尝试使用json.dumps对这个类的实例进行序列化,如果直接调用会报错,阐述报错原因,并给出至少两种解决这个问题的方案,同时解释每种方案的优缺点。
47.1万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

报错原因

json.dumps 只能序列化基本数据类型(如字典、列表、字符串、数字、布尔值、None),而自定义类 MyClass 的实例不属于这些基本类型,所以直接调用会报错。

方案一:转换为字典

  1. 实现方式
import json


class MyClass:
    def __init__(self):
        self.attr1 = 'value1'
        self.attr2 = 42


obj = MyClass()
data_dict = {
    'attr1': obj.attr1,
    'attr2': obj.attr2
}
json_str = json.dumps(data_dict)
print(json_str)
  1. 优点
    • 简单直接,容易理解和实现。
    • 不需要额外的复杂操作,对于简单的自定义类很适用。
  2. 缺点
    • 如果类中有很多属性,手动构建字典会很繁琐,容易出错。
    • 对于类中属性结构复杂(如嵌套自定义类等)的情况,处理起来比较困难。

方案二:使用 __dict__ 属性

  1. 实现方式
import json


class MyClass:
    def __init__(self):
        self.attr1 = 'value1'
        self.attr2 = 42


obj = MyClass()
json_str = json.dumps(obj.__dict__)
print(json_str)
  1. 优点
    • 代码简洁,一行代码即可实现序列化,对于属性较多的类也很方便。
    • 自动包含所有实例属性,无需手动列举每个属性。
  2. 缺点
    • 可能会序列化一些不希望被序列化的内部属性(如果类中定义了以双下划线开头的私有属性,在 Python 中实际上是会变形为 _ClassName__attr 形式存在于 __dict__ 中的)。
    • 对于类中属性是复杂类型(如自定义类对象),仍然无法直接序列化,需要进一步处理。

方案三:自定义 JSONEncoder

  1. 实现方式
import json


class MyClass:
    def __init__(self):
        self.attr1 = 'value1'
        self.attr2 = 42


class MyEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, MyClass):
            return {
                'attr1': o.attr1,
                'attr2': o.attr2
            }
        return super().default(o)


obj = MyClass()
json_str = json.dumps(obj, cls=MyEncoder)
print(json_str)
  1. 优点
    • 更加灵活,可以根据需要定制序列化逻辑,适用于各种复杂的自定义类结构。
    • 可以处理不同类型的自定义类,通过 isinstance 判断并进行相应处理。
  2. 缺点
    • 代码相对复杂,需要定义一个自定义的 JSONEncoder 类,增加了代码量。
    • 如果类结构发生变化,需要修改 default 方法中的序列化逻辑,维护成本相对较高。