You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python标准库JSON序列化时排除指定字段及父类内容?

嘿,这个问题我熟!完全不用新建额外的对象层级,用Python标准库的json模块就能搞定选择性序列化,甚至能精准排除父类的所有内容。我给你几个实用的方案:

方案1:活用default参数做动态筛选

你说的default参数其实不止能处理不可序列化的对象——我们可以在里面写逻辑,直接把自定义对象转换成只包含需要字段的字典,同时排除父类属性和不需要的子对象。

先看示例代码:

import json

class BaseItemClass:
    def __init__(self):
        self.base_property = "我是父类属性,不要序列化我"

class MyItemClass(BaseItemClass):
    def __init__(self):
        super().__init__()
        self.saveThisProperty = "要保留的属性"
        self.dontSaveThisProperty = "要排除的属性"
        self.saveThisObject = MySubItem()  # 要保留的子对象
        self.dontSaveThisObject = MySubItem()  # 要排除的子对象

class MySubItem:
    def __init__(self):
        self.sub_save_prop = "子对象要保留的属性"
        self.sub_dont_save_prop = "子对象要排除的属性"

def selective_serializer(obj):
    # 处理MyItemClass实例:排除父类属性+指定字段
    if isinstance(obj, MyItemClass):
        # 定义要保留的字段列表
        allowed_fields = {"saveThisProperty", "saveThisObject"}
        # 只保留当前类自己的属性(排除父类继承的)
        own_attributes = {k: v for k, v in obj.__dict__.items() 
                          if not hasattr(BaseItemClass, k)}
        # 筛选出需要保留的字段
        filtered_data = {k: v for k, v in own_attributes.items() 
                         if k in allowed_fields}
        # 递归处理子对象(比如saveThisObject)
        for key, value in filtered_data.items():
            if not isinstance(value, (str, int, float, bool, type(None))):
                filtered_data[key] = selective_serializer(value)
        return filtered_data
    
    # 处理子对象MySubItem:同样筛选字段
    elif isinstance(obj, MySubItem):
        return {"sub_save_prop": obj.sub_save_prop}
    
    # 其他类型交给默认序列化逻辑
    raise TypeError(f"无法序列化类型: {type(obj)}")

# 测试序列化
my_item = MyItemClass()
json_result = json.dumps(my_item, default=selective_serializer, indent=2)
print(json_result)

这个方法的核心是:在序列化时动态生成只包含必要内容的字典,完全不用提前复制对象。和XML按需输出节点的思路一致——你精准控制哪些内容被纳入序列化流程。

方案2:给类定义__json__方法(更模块化)

如果希望每个类自己掌控要序列化的内容,可以给类加一个__json__方法,然后在default里调用这个方法:

# 给MyItemClass添加__json__方法
class MyItemClass(BaseItemClass):
    # ... 之前的__init__不变 ...
    
    def __json__(self):
        return {
            "saveThisProperty": self.saveThisProperty,
            "saveThisObject": self.saveThisObject.__json__()
        }

# 给MySubItem添加__json__方法
class MySubItem:
    # ... 之前的__init__不变 ...
    
    def __json__(self):
        return {"sub_save_prop": obj.sub_save_prop}

# 简化后的default函数
def json_default(obj):
    if hasattr(obj, "__json__"):
        return obj.__json__()
    raise TypeError(f"无法序列化类型: {type(obj)}")

# 测试
json_result = json.dumps(my_item, default=json_default, indent=2)

这种方式更清晰,每个类的序列化规则都封装在自己的方法里,后期维护起来更方便。

方案3:继承JSONEncoder(更面向对象)

如果喜欢用类的方式组织逻辑,可以继承json.JSONEncoder,重写default方法:

class SelectiveEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, MyItemClass):
            return {
                "saveThisProperty": obj.saveThisProperty,
                "saveThisObject": self.default(obj.saveThisObject)
            }
        elif isinstance(obj, MySubItem):
            return {"sub_save_prop": obj.sub_save_prop}
        return super().default(obj)

# 测试
json_result = json.dumps(my_item, cls=SelectiveEncoder, indent=2)

这个方案和方案1逻辑类似,但用类的方式封装,适合复杂的序列化场景。

总结一下:你完全不需要新建独立的对象层级,以上三种方法都是在序列化过程中动态筛选内容,和XML按需输出节点的思路一致。default参数(或JSONEncoder的default方法)不仅能处理不可序列化对象,还能帮我们实现精准的选择性序列化。

内容的提问来源于stack exchange,提问作者JonBrave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:52:34