当前位置: 首页 > 面试题库 >

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

易自珍
2023-03-14
问题内容

我有一个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
的值,还是只是查看整个对象的通用包含/丢弃?该方法如何容纳嵌套值?我已经看过以前的问题,但似乎找不到最佳的针对特定情况的编码的方法(不幸的是,这似乎是我在这里需要做的事情)。


问题答案:

JSON表示法只有少数本机数据类型(对象,数组,字符串,数字,布尔值和null),因此以JSON序列化的任何内容都必须表示为这些类型之一。

如json模块docs所示,此转换可以由
JSONEncoderJSONDecoder
自动完成,但随后您将放弃可能需要的其他一些结构(如果将集转换为列表,则将失去恢复常规数据的能力。列表;如果使用将集转换为字典,dict.fromkeys(s)则将失去恢复字典的能力)。

一个更复杂的解决方案是构建可以与其他本机JSON类型共存的自定义类型。这使您可以存储包括列表,集合,字典,小数,日期时间对象等的嵌套结构:

from json import dumps, loads, JSONEncoder, JSONDecoder
import pickle

class PythonObjectEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, (list, dict, str, unicode, int, float, bool, type(None))):
            return JSONEncoder.default(self, obj)
        return {'_python_object': pickle.dumps(obj)}

def as_python_object(dct):
    if '_python_object' in dct:
        return pickle.loads(str(dct['_python_object']))
    return dct

这是一个示例会话,显示它可以处理列表,字典和集合:

>>> data = [1,2,3, set(['knights', 'who', 'say', 'ni']), {'key':'value'}, Decimal('3.14')]

>>> j = dumps(data, cls=PythonObjectEncoder)

>>> loads(j, object_hook=as_python_object)
[1, 2, 3, set(['knights', 'say', 'who', 'ni']), {u'key': u'value'}, Decimal('3.14')]

另外,使用更通用的序列化技术(例如YAML,Twisted
Jelly或Python的pickle模块)可能很有用。它们每个都支持更大范围的数据类型。



 类似资料:
  • 问题内容: Python通过按顺序查看元组的元素来对元组列表进行排序。由于集合是无序的,Python如何对集合列表进行排序? 编辑:帖子中的问题和可接受的答案较为笼统,给出的文件也很深入。我的问题不是重复的。 问题答案: 无论列表中有什么内容,元素的方法都是唯一参考的比较方法。对于集合,意味着“是”的适当子集,不足以定义总顺序。这就是为什么结果通常是不确定的。可能是原始列表的任何排列,与实现恰好适

  • 问题内容: 我有一个像这样的简单容器类的结构(在伪红宝石中): 有没有简单的方法可以在Ruby中将其反序列化为JSON?还是应该像本例一样为每个类制作嵌套的序列化方法? 编辑: 在我的特定情况下,我想将一些JSON数据发布到运行Ruby的服务器上,该服务器将提取数据并采取相应的措施。 JSON的发送者不一定是Ruby进程,而可能是其他系统的后端。(尽管在我的测试工具中是Ruby)。 因此,我不需要

  • 所以我正在使用日期列表,其中一些值是""即null。我使用了如何在使用集合排序时处理空值Java答案 以两种升序对列表进行排序,将空放在第一位。 我想要的是按升序排列,先有空值,然后像上面的代码一样按升序排列。然后当选择降序来翻转列表时。列表中的第一个值是按降序排列的,然后是所有的空值。 在我按照集合的升序对列表排序后,我尝试了以下操作。反转顺序() 首先保留空值,然后按降序排列日期。 我还尝试了

  • 本文向大家介绍JAVA对list集合进行排序Collections.sort(),包括了JAVA对list集合进行排序Collections.sort()的使用技巧和注意事项,需要的朋友参考一下 对一个集合中的对象进行排序,根据对象的某个指标的大小进行升序或降序排序。代码如下: 进行降序排列 进行升序排列 经过测试发现,只需要把两个对象的位置调换一下即可升序或降序。 如果指标相同,根据多个指标进行

  • 问题内容: 我将MongoDB与Node.JS结合使用。我有一个包含日期和其他行的集合。日期是一个JavaScript 对象。 如何按日期排序此收藏集? 问题答案: 只需对@JohnnyHK答案进行一些修改 在许多用例中,我们希望返回最新记录(例如最新更新/插入)。

  • 问题内容: 假设我有两个类CLassA和CLassB。它们有一个共同的属性,例如每个类拥有的元素数量。 我如何从ClassA和CLassB的对象创建一个集合,并按该属性排序(降序升序无所谓)? 我收集了一个类型,但是当我尝试实现Comparable Interface时,我无法使用该方法(例如,获取返回元素nr的get)。 我有什么解决方案? 谢谢你的帮助! 问题答案: 实际上,如果要将它们放在同