我试图创建一个类实例的JSON字符串表示,有困难。假设这个类是这样构建的:

class testclass:
    value1 = "a"
    value2 = "b"

对json的调用。转储是这样的:

t = testclass()
json.dumps(t)

它失败了,告诉我测试类不是JSON序列化的。

TypeError: <__main__.testclass object at 0x000000000227A400> is not JSON serializable

我也尝试过使用pickle模块:

t = testclass()
print(pickle.dumps(t, pickle.HIGHEST_PROTOCOL))

它提供类实例的信息,而不是类实例的序列化内容。

b'\x80\x03c__main__\ntestclass\nq\x00)\x81q\x01}q\x02b.'

我做错了什么?


当前回答

有一种方法非常适合我,你可以试试:

Json.dumps()可以接受一个可选参数default,您可以在其中为未知类型指定一个自定义序列化器函数,在我的例子中是这样的

def serialize(obj):
    """JSON serializer for objects not serializable by default json code"""

    if isinstance(obj, date):
        serial = obj.isoformat()
        return serial

    if isinstance(obj, time):
        serial = obj.isoformat()
        return serial

    return obj.__dict__

前两个if用于日期和时间序列化 然后有一个obj。为任何其他对象返回__dict__。

最终决定是这样的:

json.dumps(myObj, default=serialize)

当你在序列化一个集合,并且你不想为每个对象显式地调用__dict__时,它特别好。这里是自动完成的。

到目前为止对我来说很好,期待你的想法。

其他回答

你可以使用Jsonic将几乎任何东西序列化为JSON:

https://github.com/OrrBin/Jsonic

例子:

class TestClass:
def __init__(self):
    self.x = 1
    self.y = 2

instance = TestClass()
s = serialize(instance): # instance s set to: {"x":1, "y":2}
d = deserialize(s) # d is a new class instance of TestClass

Jsonic有一些不错的特性,比如声明类属性为瞬态的和类型安全的反序列化。

(晚了几年才有答案,但我认为这可能会对其他人有所帮助)

使用任意的可扩展对象,然后将其序列化为JSON:

import json

class Object(object):
    pass

response = Object()
response.debug = []
response.result = Object()

# Any manipulations with the object:
response.debug.append("Debug string here")
response.result.body = "404 Not Found"
response.result.code = 404

# Proper JSON output, with nice formatting:
print(json.dumps(response, indent=4, default=lambda x: x.__dict__))

有一种方法非常适合我,你可以试试:

Json.dumps()可以接受一个可选参数default,您可以在其中为未知类型指定一个自定义序列化器函数,在我的例子中是这样的

def serialize(obj):
    """JSON serializer for objects not serializable by default json code"""

    if isinstance(obj, date):
        serial = obj.isoformat()
        return serial

    if isinstance(obj, time):
        serial = obj.isoformat()
        return serial

    return obj.__dict__

前两个if用于日期和时间序列化 然后有一个obj。为任何其他对象返回__dict__。

最终决定是这样的:

json.dumps(myObj, default=serialize)

当你在序列化一个集合,并且你不想为每个对象显式地调用__dict__时,它特别好。这里是自动完成的。

到目前为止对我来说很好,期待你的想法。

我一直在我的Flask应用程序中使用的一种方法,将类实例序列化为JSON响应。

Github项目供参考

from json import JSONEncoder
import json
from typing import List

class ResponseEncoder(JSONEncoder):
    def default(self, o):
        return o.__dict__

class ListResponse:
    def __init__(self, data: List):
        self.data = data
        self.count = len(data)

class A:
    def __init__(self, message: str):
        self.message = message

class B:
    def __init__(self, record: A):
        self.record = record

class C:
    def __init__(self, data: B):
        self.data = data

现在创建一个A, B, C的实例,然后编码。

data_a = A('Test Data')
data_b = B(data_a)
data_c = C(data_b)

response = ResponseEncoder().encode(data_c)
json_response = json.loads(response)

输出

{
    "data": {
        "record": {
            "message": "Test Data"
        }
    }
}

对于列表类型响应

records = ['One', 'Two', 'Three']
list_response = ListResponse(records)
response = ResponseEncoder().encode(list_response)
json_response = json.loads(response)

输出

{
    "data": [
        "One",
        "Two",
        "Three"
    ],
    "count": 3
}

我认为,与其像公认的答案中建议的那样继承,不如使用多态。否则你必须有一个大的if else语句来自定义每个对象的编码。这意味着为JSON创建一个通用的默认编码器:

def jsonDefEncoder(obj):
   if hasattr(obj, 'jsonEnc'):
      return obj.jsonEnc()
   else: #some default behavior
      return obj.__dict__

然后在你想序列化的每个类中都有一个jsonEnc()函数。如。

class A(object):
   def __init__(self,lengthInFeet):
      self.lengthInFeet=lengthInFeet
   def jsonEnc(self):
      return {'lengthInMeters': lengthInFeet * 0.3 } # each foot is 0.3 meter

然后调用json.dumps(classInstance,default=jsonDefEncoder)