代码之家  ›  专栏  ›  技术社区  ›  Atul

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

  •  0
  • Atul  · 技术社区  · 4 年前

    我无法在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 但这并没有多大帮助

    2 回复  |  直到 4 年前
        1
  •  1
  •   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\"}"]}
    
        2
  •  -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)