如何使用 jsonpickle 排除序列化的特定字段?

Posted

技术标签:

【中文标题】如何使用 jsonpickle 排除序列化的特定字段?【英文标题】:How to exclude specific fields on serialization with jsonpickle? 【发布时间】:2013-08-11 10:18:46 【问题描述】:

我正在使用带有 Flask 的 SQLAlchemy 扩展。在使用 jsonpickle 序列化我的模型 (也用于数据库操作) 时,我希望忽略一些特定属性。有没有办法让我设置这些规则?

SQLAlchemy 向对象添加了一个名为 _sa_instance_state 的属性。总之,我不希望这个字段出现在 JSON 输出中。

【问题讨论】:

【参考方案1】:

你不能告诉默认类选择器忽略某些东西,不。

jsonpickle 确实支持 pickle module __getstate____setstate__ 方法。如果您的类实现了这两种方法,则返回的任何内容都会被 jsonpickle 用来表示状态。这两种方法都需要实现。

如果__getstate__没有实现,jsonpickle 使用__dict__ 属性代替,所以你自己的版本只需要使用同一个字典,删除_sa_instance_state 键,你就是完成:

def __getstate__(self):
    state = self.__dict__.copy()
    del state['_sa_instance_state']
    return state

def __setstate__(self, state):
    self.__dict__.update(state)

无论__getstate__ 返回什么都将被进一步递归处理,无需担心在那里处理子对象。

如果不能添加__getstate____setstate__,您也可以为您的班级注册custom serialization handler;缺点是虽然__getstate__ 可以只返回一个字典,但自定义处理程序需要返回一个完全展平的值。

【讨论】:

添加 __getstate____setstate__ 现在就像一个魅力,谢谢。与其为每个模型编写相同的代码行,不如实现一个装饰器来从 __dict__ 中删除被忽略的字段,这对于未来可能是一个好主意。 我赞同 mkubilayk 对未来功能的期望,它非常类似于 .NET 的 xml 序列化的 XmlAttributes.XmlIgnore Property【参考方案2】:

这将帮助其他人完成任务:

在您的自定义 jsonpickle 包这样的包中创建一个这样的类:

class SetGetState:
    def __getstate__(self):
        state = self.__dict__.copy()
        try:
            class_name = '_' + self.__class__.__name__ + '__'
            new_items = key:value for key, value in state.items() if class_name not in key
            return new_items
        except KeyError:
            pass
        return state

并且继承这个类中不需要私有属性序列化

class Availability(jsonpickle.SetGetState):
    pass

【讨论】:

以上是关于如何使用 jsonpickle 排除序列化的特定字段?的主要内容,如果未能解决你的问题,请参考以下文章

Python 序列化JsonPickle

jsonpickle

Python—序列化和反序列化模块(jsonpickle和shelve)

使用 jsonpickle 从文件中保存和加载对象

如何从 Json 序列化中排除属性

如何使用 ConstraintMapping 排除码头中的特定路径?