为了账号安全,请及时绑定邮箱和手机立即绑定

如何对集合进行JSON序列化?

如何对集合进行JSON序列化?

慕运维8079593 2019-10-05 14:13:22
我有一个Python set,其中包含带有__hash__和__eq__方法的对象,以确保该集合中没有重复项。我需要对该结果进行json编码set,但是即使将一个空值传递set给该json.dumps方法也会引发TypeError。  File "/usr/lib/python2.7/json/encoder.py", line 201, in encode    chunks = self.iterencode(o, _one_shot=True)  File "/usr/lib/python2.7/json/encoder.py", line 264, in iterencode    return _iterencode(o, 0)  File "/usr/lib/python2.7/json/encoder.py", line 178, in default    raise TypeError(repr(o) + " is not JSON serializable")TypeError: set([]) is not JSON serializable我知道我可以为json.JSONEncoder具有自定义default方法的类创建扩展,但是我什至不确定从哪里开始转换set。我是否应该set使用默认方法中的值创建字典,然后返回该方法的编码?理想情况下,我想使默认方法能够处理原始编码器阻塞的所有数据类型(我将Mongo用作数据源,所以日期似乎也引发了此错误)向正确方向的任何提示将不胜感激。编辑:感谢您的回答!也许我应该更精确一些。我利用(并赞成)这里的答案来解决set翻译的局限性,但是内部键也是一个问题。中的set对象是转换为的复杂对象__dict__,但它们本身也可以包含其属性值,这些值可能不符合json编码器中的基本类型。涉及到很多不同的类型set,哈希基本上为实体计算了一个唯一的id,但是按照NoSQL的真正精神,没有确切说明子对象包含什么。一个对象可能包含的日期值starts,而另一个对象可能具有其他不包含“非原始”对象键的其他模式。这就是为什么我唯一能想到的解决方案是扩展JSONEncoder替换default方法以打开不同情况的方法-但我不确定如何解决此问题,并且文档不明确。在嵌套对象中,是default按键返回go 的值,还是只是查看整个对象的通用包含/丢弃?该方法如何容纳嵌套值?我已经看过以前的问题,但似乎找不到最佳的针对特定情况的编码的方法(不幸的是,这似乎是我在这里需要做的事情)。
查看完整描述

3 回答

?
达令说

TA贡献1821条经验 获得超6个赞

您可以创建一个自定义编码器,list当遇到时会返回set。这是一个例子:


>>> import json

>>> class SetEncoder(json.JSONEncoder):

...    def default(self, obj):

...       if isinstance(obj, set):

...          return list(obj)

...       return json.JSONEncoder.default(self, obj)

... 

>>> json.dumps(set([1,2,3,4,5]), cls=SetEncoder)

'[1, 2, 3, 4, 5]'

您也可以通过这种方式检测其他类型。如果需要保留列表实际上是一个集合,则可以使用自定义编码。喜欢的东西return {'type':'set', 'list':list(obj)}可能会奏效。


要说明嵌套类型,请考虑将其序列化:


>>> class Something(object):

...    pass

>>> json.dumps(set([1,2,3,4,5,Something()]), cls=SetEncoder)

这将引发以下错误:


TypeError: <__main__.Something object at 0x1691c50> is not JSON serializable

这表明编码器将获取list返回的结果,并对其子代递归调用序列化器。要为多种类型添加自定义序列化程序,可以执行以下操作:


>>> class SetEncoder(json.JSONEncoder):

...    def default(self, obj):

...       if isinstance(obj, set):

...          return list(obj)

...       if isinstance(obj, Something):

...          return 'CustomSomethingRepresentation'

...       return json.JSONEncoder.default(self, obj)

... 

>>> json.dumps(set([1,2,3,4,5,Something()]), cls=SetEncoder)

'[1, 2, 3, 4, 5, "CustomSomethingRepresentation"]'


查看完整回答
反对 回复 2019-10-05
  • 3 回答
  • 0 关注
  • 732 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信