我定义了一个类,A
并且使用了A
其他类、容器和嵌套类型内部的对象。
例子
a = A()
b = [a,3,'hello'
c = {'hey': b, 'huy': 3}
d = [a,b,c]
我对 的 json 表示感兴趣d
,所以当然我必须指定遇到A
.
对于 'A' 类的对象,我想得到这个(请注意,我正在跳过 att2,这表明我不知道使用类似的东西a.__dict__
):
{
class_name = 'A',
att1 = '<value of att1>',
att3 = '<value of att3>'
}
att1 可以是任何东西:A
实例、默认类型等。
我希望能够调用json.dumps(d)
并获得所需的输出,所以我想做的是告诉类A
在 json 序列化程序询问时输出什么。
我环顾四周,我只找到了一个复杂的解决方案,其中传递了一个 lambda 或一个类json.dumps()
,我不明白为什么不只是覆盖 json 序列化程序调用的方法,比如覆盖__str__()
或__repr__()
.
也许这是不可能的?在这种情况下,在我的情况下什么是简单的解决方案?请注意,在我的实际问题中,我不仅有类,A
还有嵌套在一起的各种自定义类,因此覆盖默认序列化程序将是自然而简单的解决方案。
我的尝试之一
我正在尝试遵循encoder.py第160行的建议
所以A
从子类化json.JSONEncoder
,我声明了方法
def default(self,obj):
return 'valid custom json representation of A'
但这不起作用,并且引发了上述链接第 179 行的异常。我的代码有什么问题?
默认的 JSON 编码器(您链接到的)只知道如何处理“简单”的东西,比如字典、列表、字符串和数字。它不尝试序列化类,因此没有可以在类上实现的“特殊”方法以使其可 JSON 序列化。基本上,如果你想使用json.dumps
,你将不得不传递一些额外的东西以使其与你的自定义类一起工作。
当编码器不知道如何处理对象时,它会调用该default
方法。根据您的问题,我相信您已经发现了这一点,但是您对该default
方法应该去哪里感到有些困惑。这是一个可以满足您要求的示例:
import json
def default(o):
if hasattr(o, 'to_json'):
return o.to_json()
raise TypeError(f'Object of type {o.__class__.__name__} is not JSON serializable')
class A(object):
def __init__(self):
self.data = 'stuff'
self.other_data = 'other stuff'
def to_json(self):
return {'data': self.data}
a = A()
b = [a, 3, 'hello']
c = {'hey': b, 'huy': 3}
d = [a, b, c]
print(json.dumps(d, default=default))
打印出来:
[{"data": "stuff"}, [{"data": "stuff"}, 3, "hello"], {"hey": [{"data": "stuff"}, 3, "hello"], "huy": 3}]
请注意,每个自定义类to_json
现在只需要实现该方法,一切都会正确序列化(假设您default
在调用 时传入自定义函数json.dumps
)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句