MST

星途 面试题库

面试题:自定义Python字典序列化与反序列化方案

假设不允许使用Python标准库中的JSON模块,需要你自定义实现一套字典的序列化与反序列化机制。要求支持常见的Python数据类型(如字符串、数字、列表、字典等),并且考虑如何处理循环引用的字典结构(例如,字典A中有一个键指向字典A本身)。请详细说明设计思路,并给出关键代码实现。
10.5万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 序列化
    • 对于常见的数据类型(字符串、数字、列表、字典),采用递归的方式进行处理。
    • 为了处理循环引用,使用一个集合来记录已经处理过的对象。当遇到一个对象时,先检查该对象是否在集合中,如果在,表示存在循环引用,需要特殊处理(比如用一个占位符表示)。
    • 字符串直接转换为自身,数字同理。
    • 列表则遍历每个元素,递归调用序列化函数处理每个元素并组成新的列表。
    • 字典同样递归处理每个键值对,将键和值都进行序列化。
  2. 反序列化
    • 与序列化相对应,同样采用递归方式。
    • 对于之前处理循环引用的占位符,在反序列化时需要恢复正确的引用关系。这里可以使用一个字典来记录已经反序列化的对象,当遇到占位符时,从该字典中获取正确的对象引用。

关键代码实现

# 用于标记循环引用的占位符
CYCLE_PLACEHOLDER = '__CYCLE__'


def custom_serialize(obj, memo=None):
    if memo is None:
        memo = set()
    if id(obj) in memo:
        return CYCLE_PLACEHOLDER
    memo.add(id(obj))
    if isinstance(obj, str):
        return obj
    elif isinstance(obj, (int, float)):
        return obj
    elif isinstance(obj, list):
        return [custom_serialize(item, memo) for item in obj]
    elif isinstance(obj, dict):
        serialized_dict = {}
        for key, value in obj.items():
            serialized_key = custom_serialize(key, memo)
            serialized_value = custom_serialize(value, memo)
            serialized_dict[serialized_key] = serialized_value
        return serialized_dict
    else:
        raise TypeError(f"Unsupported type {type(obj)}")


def custom_deserialize(obj, memo=None):
    if memo is None:
        memo = {}
    if isinstance(obj, str) and obj == CYCLE_PLACEHOLDER:
        return next(iter(memo.values()))
    elif isinstance(obj, list):
        return [custom_deserialize(item, memo) for item in obj]
    elif isinstance(obj, dict):
        deserialized_dict = {}
        for key, value in obj.items():
            deserialized_key = custom_deserialize(key, memo)
            deserialized_value = custom_deserialize(value, memo)
            deserialized_dict[deserialized_key] = deserialized_value
            if deserialized_key == CYCLE_PLACEHOLDER:
                memo[CYCLE_PLACEHOLDER] = deserialized_dict
        return deserialized_dict
    else:
        return obj


你可以使用以下方式测试代码:

# 测试示例
test_dict = {'a': 1, 'b': [2, 3], 'c': {'d': 4}}
serialized = custom_serialize(test_dict)
print(serialized)
deserialized = custom_deserialize(serialized)
print(deserialized)

# 测试循环引用
circular_dict = {}
circular_dict['self_ref'] = circular_dict
serialized_circular = custom_serialize(circular_dict)
print(serialized_circular)
deserialized_circular = custom_deserialize(serialized_circular)
print(deserialized_circular)