Py学习  »  Python

json。转储不使用自定义python对象

Atul • 4 年前 • 2031 次点击  

我无法在python 3中序列化自定义对象。 下面是解释和代码

packages= []
data = {
    "simplefield": "value1",
    "complexfield": packages,
}

其中packages是一个 custom object Library . Library object 下面是一个班级(我也有子班级) json.JSONEncoder 但这没有帮助)

class Library(json.JSONEncoder):
def __init__(self, name):
    print("calling Library constructor ")
    self.name = name

def default(self, object):
    print("calling default method ")
    if isinstance(object, Library):
        return {
            "name": object.name
        }
    else:
        raiseExceptions("Object is not instance of Library")

现在我打电话 json.dumps(data) 但这是一个例外。

TypeError: Object of type `Library` is not JSON serializable 

看来 "calling default method" 不是印刷的意思, Library.default 方法不被调用

有人能帮忙吗?

我还提到 Serializing class instance to JSON 但这并没有多大帮助

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/128393
文章 [ 2 ]  |  最新文章 4 年前
Bharel
Reply   •   1 楼
Bharel    4 年前

你可以使用 default 参数 json.dump :

def default(obj):
  if isinstance(obj, Library):
      return {"name": obj.name}
  raise TypeError(f"Can't serialize {obj!r}.")

json.dumps(data, default=default)
Kris
Reply   •   2 楼
Kris    4 年前

继承 json.JSONEncoder 不会使类可序列化。您应该单独定义编码器,然后在 json.dumps 呼叫

参见下面的示例方法

import json
from typing import Any


class Library:
    def __init__(self, name):
        print("calling Library constructor ")
        self.name = name

    def __repr__(self):
        # I have just created a serialized version of the object
        return '{"name": "%s"}' % self.name

# Create your custom encoder
class CustomEncoder(json.JSONEncoder):

    def default(self, o: Any) -> Any:
        # Encode differently for different types
        return str(o) if isinstance(o, Library) else super().default(o)


packages = [Library("package1"), Library("package2")]
data = {
    "simplefield": "value1",
    "complexfield": packages,
}
#Use your encoder while serializing
print(json.dumps(data, cls=CustomEncoder))

输出结果如下:

{"simplefield": "value1", "complexfield": ["{\"name\": \"package1\"}", "{\"name\": \"package2\"}"]}