如何用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
相关产品推荐
相关产品推荐

