在实现JSONPICKLE自定义处理程序时,如何处理单个值



我为jsonpickle编写了一个自定义处理程序,以便在序列化对象容器之前转换枚举值。

import jsonpickle
from enum import Enum

class Bar(Enum):
    A = 1
    B = 2

class Foo:
    def __init__(self):
        self.hello = 'hello'
        self.bar = [Bar.A, Bar.B]

class Handler(jsonpickle.handlers.BaseHandler):
    def flatten(self, obj, data):  # data contains {}
        print(obj)
        ### How should I handle the enum? ###
        return data

jsonpickle.handlers.registry.register(Bar, Handler)

def main():
    fizbuz = Foo()
    encoded = jsonpickle.encode(fizbuz)
    print(encoded)

if __name__ == '__main__':
    main()

使用包含枚举值的OBJ调用处理程序。但是,数据dict已经包含一个键,值对,因此我不能仅返回代表枚举的单个值。

所以我的问题是,当我是在返回一个唯一值时,我需要将其添加到数据时,我需要将其添加到数据dict中,而我需要将其符合在数据dact中的数据dact pre = pre = - 用反射数据填充,以稍后重建对象。

我不明白您为什么担心所提供的dict?这是您用于帮助您的处理程序代码的输入,如果您不想要它,则根本不需要使用。如您所指示的那样,它不是{},如果您使用nocklable = false的编码。如果您不包括在内,那么您实际上会得到:

{'py/object': '__main__.Bar'}

所有提供的是变量的类型,您写了处理程序,因此您自然知道类型。

如果您想要枚举的良好JSON输出,只需告诉Python,Flatten功能的OBJ是条类型(可选,但对IDE和以后的维护(,例如:

def flatten(self, obj: Bar, data):

然后,只需返回obj.name即可。这样做,输出为:

{"py/object": "__main__.Foo", "bar": ["A", "B"], "hello": "hello"}

当然,我们可以通过告诉编码器不必担心以后再解码来使其更加清洁:

unpicklable=False

最终输出是:

{"bar": ["A", "B"], "hello": "hello"}

整个示例代码:

import jsonpickle
from enum import Enum

class Bar(Enum):
    A = 1
    B = 2

class Foo:
    def __init__(self):
        self.hello = 'hello'
        self.bar = [Bar.A, Bar.B]

class Handler(jsonpickle.handlers.BaseHandler):
    def flatten(self, obj: Bar, data):
        print(obj)
        return obj.name

jsonpickle.handlers.registry.register(Bar, Handler)

def main():
    fizbuz = Foo()
    encoded = jsonpickle.encode(fizbuz, unpicklable=False)
    print(encoded)

if __name__ == '__main__':
    main()

通用方法

您也可以使用类似的类来一般处理所有枚举:

from enum import Enum
import jsonpickle

class JsonEnumHandler(jsonpickle.handlers.BaseHandler):
    def restore(self, obj):
        pass
    def flatten(self, obj: Enum, data):
        return obj.name

然后,像这样注册JSON中的所有枚举:

    jsonpickle.handlers.registry.register(LimitType, JsonEnumHandler)
    jsonpickle.handlers.registry.register(DeviceType, JsonEnumHandler)

最新更新