为什么python中的默认JSONEncoder不能序列化abc.Sequence和abc.Mappings?
因此,如果我们创建一些类,实现为什么python中的默认JSONEncoder不能序列化abc.Sequence和abc.Mappings?,python,json,typeerror,Python,Json,Typeerror,因此,如果我们创建一些类,实现collections.abc.MutableSequence,和list就是这样一个例子 class Woof(collections.MutableSequence): def __init__(self, data=[]): self.s = list(data) def __setitem__(self, k, v): self.s[k] = v def __getitem__(self,k):
collections.abc.MutableSequence
,和list
就是这样一个例子
class Woof(collections.MutableSequence):
def __init__(self, data=[]):
self.s = list(data)
def __setitem__(self, k, v):
self.s[k] = v
def __getitem__(self,k):
return self.s[k]
def __delitem__(self,k):
del self.s[k]
def __repr__(self):
return repr(self.s)
def __len__(self):
return len(self.s)
def insert(self,k,v):
self.s[k] = v
我们无法将其实例传递给默认的JSONEncoder
>>> w = Woof(range(5,10))
>>> json.dumps(w)
TypeError: [5, 6, 7, 8, 9] is not JSON serializable
问题不在于如何序列化自定义类,而在于为什么python只能序列化它自己的
序列和映射的实现,而不是实现完全相同的接口的任意实现,标准库的模块知道如何将列表和元组编码为JSON,因为这种支持是显式内置到模块中的
您会注意到,代码对collections.MutableSequence或其自定义子类一无所知;这就是为什么您的json.dumps(w)
调用失败并出现TypeError。在JSONEncoder.default()中,有一些函数可以用来定义函数的子类,以支持序列化类 据我所知,鲍勃·伊波利托(Bob Ippolito)(本书的主要作者,他也对stdlib进行了修改,并对stdlib版本进行了大部分维护)从未给出过他的理由,因此如果你真的想知道,你唯一能做的就是问他
但我认为有一个显而易见的答案:如果将所有Sequence
类型编码到JSON数组中,那么在解码时就无法区分Sequence
类型之间的差异。而且,由于某种原因,并且由于json
模块无法预测的原因,您的代码可能使用的不是list
,它可能会丢弃重要信息
这就是说,想要像对待list
一样对待其他序列类型,甚至是任意的iterables,这是一个非常常见的用例,如果您想要的话,它很容易做到,而且非常简单