如何使类 JSON 可序列化

2022-09-05 01:02:47

如何使Python类可序列化?

class FileItem:
    def __init__(self, fname):
        self.fname = fname

尝试序列化为 JSON:

>>> import json
>>> x = FileItem('/foo/bar')
>>> json.dumps(x)
TypeError: Object of type 'FileItem' is not JSON serializable

答案 1

以下是简单功能的简单解决方案:

.toJSON()方法

实现一个序列化程序方法,而不是 JSON 可序列化类:

import json

class Object:
    def toJSON(self):
        return json.dumps(self, default=lambda o: o.__dict__, 
            sort_keys=True, indent=4)

因此,您只需调用它来序列化:

me = Object()
me.name = "Onur"
me.age = 35
me.dog = Object()
me.dog.name = "Apollo"

print(me.toJSON())

将输出:

{
    "age": 35,
    "dog": {
        "name": "Apollo"
    },
    "name": "Onur"
}

答案 2

您对预期输出有想法吗?例如,这能行吗?

>>> f  = FileItem("/foo/bar")
>>> magic(f)
'{"fname": "/foo/bar"}'

在这种情况下,您只能调用 .json.dumps(f.__dict__)

如果你想要更多自定义输出,那么你将不得不子类JSONEncoder并实现你自己的自定义序列化。

有关简单示例,请参阅下文。

>>> from json import JSONEncoder
>>> class MyEncoder(JSONEncoder):
        def default(self, o):
            return o.__dict__    

>>> MyEncoder().encode(f)
'{"fname": "/foo/bar"}'

然后,将此类作为 kwarg 传递给 json.dumps() 方法:cls

json.dumps(cls=MyEncoder)

如果您还想解码,则必须为JSONDecoder类提供自定义。例如:object_hook

>>> def from_json(json_object):
        if 'fname' in json_object:
            return FileItem(json_object['fname'])
>>> f = JSONDecoder(object_hook = from_json).decode('{"fname": "/foo/bar"}')
>>> f
<__main__.FileItem object at 0x9337fac>
>>>