我试图创建一个类实例的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.'

我做错了什么?


当前回答

我只会:

data=json.dumps(myobject.__dict__)

这不是完整的答案,如果你有某种复杂的对象类,你肯定不会得到所有的东西。然而,我在一些简单的对象中使用这种方法。

它工作得非常好的一个是您从OptionParser模块中获得的“options”类。 下面是它和JSON请求本身。

  def executeJson(self, url, options):
        data=json.dumps(options.__dict__)
        if options.verbose:
            print data
        headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
        return requests.post(url, data, headers=headers)

其他回答

我认为,与其像公认的答案中建议的那样继承,不如使用多态。否则你必须有一个大的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)

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

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有一些不错的特性,比如声明类属性为瞬态的和类型安全的反序列化。

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

我只会:

data=json.dumps(myobject.__dict__)

这不是完整的答案,如果你有某种复杂的对象类,你肯定不会得到所有的东西。然而,我在一些简单的对象中使用这种方法。

它工作得非常好的一个是您从OptionParser模块中获得的“options”类。 下面是它和JSON请求本身。

  def executeJson(self, url, options):
        data=json.dumps(options.__dict__)
        if options.verbose:
            print data
        headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
        return requests.post(url, data, headers=headers)

JSON实际上并不用于序列化任意的Python对象。它非常适合序列化dict对象,但pickle模块才是你真正应该使用的。pickle的输出实际上不是人类可读的,但它应该可以解腌。如果坚持使用JSON,可以查看jsonpickle模块,这是一种有趣的混合方法。

https://github.com/jsonpickle/jsonpickle