我为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)