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

https://github.com/jsonpickle/jsonpickle

其他回答

基本的问题是JSON编码器JSON .dumps()默认情况下只知道如何序列化有限的对象类型集,所有的内置类型。名单在这里:https://docs.python.org/3.3/library/json.html#encoders-and-decoders

一个好的解决方案是让您的类继承自JSONEncoder,然后实现JSONEncoder.default()函数,并使该函数为您的类发出正确的JSON。

一个简单的解决方案是在该实例的.__dict__成员上调用json.dumps()。这是一个标准的Python字典,如果你的类很简单,它将是JSON序列化的。

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

foo = Foo()
s = json.dumps(foo) # raises TypeError with "is not JSON serializable"

s = json.dumps(foo.__dict__) # s set to: {"x":1, "y":2}

上述方法在这篇博文中进行了讨论:

使用_dict_将任意Python对象序列化为JSON

当然,Python提供了一个内置函数,为您访问.__dict__,称为vars()。

所以上面的例子也可以这样做:

s = json.dumps(vars(foo)) # s set to: {"x":1, "y":2}

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

https://github.com/jsonpickle/jsonpickle

我只会:

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)

你可以尝试objprint,这是一个轻量级的库,用于打印Python对象,它支持json输出。

pip install objprint
from objprint import objjson
t = testclass()
json_obj = objjson(t)
print(json.dumps(json_obj))

objjson基本上将任意对象转换为jsoniizable对象,如果它不是dict, list等内置类型,则它的原始Python类型有一个特殊的键.type。

如果只是想打印它,可以使用op,它通常用于以人类可读的格式打印对象。

from objprint import op
t = testclass()
op(t, format="json", indent=2)

# If you want to dump to a file
with open("my_obj.json", "w") as f:
    # This is the same usage as print
    op(t, format="json", file=f)

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

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