Thursday, October 25, 2012

jsonpickle: JSON (de)serialization for complex Python objects

By Vasudev Ram

jsonpickle is a Python library for JSON.

From the site: "jsonpickle is a Python library for serialization and deserialization of complex Python objects to and from JSON. The standard Python libraries for encoding Python into JSON, such as the stdlib’s json, simplejson, and demjson, can only handle Python primitives that have a direct JSON equivalent (e.g. dicts, lists, strings, ints, etc.). jsonpickle builds on top of these libraries and allows more complex data structures to be serialized to JSON. jsonpickle is highly configurable and extendable–allowing the user to choose the JSON backend and add additional backends."

When I tried it with a simple example of my own, jsonpickle seems not to work quite as the docs say. E.g. Pickling an instance of a simple class Foo and then unpickling it to a different variable, results in a dict, not an instance:

>>> type(foo)
type 'instance'
>>> type(foo2)
type 'dict'

, though the dict does have the data that the instance does. May be a usage mistake or an actual bug - checking it out ...

UPDATE: Thomas K (see comments on this post) pointed out that the error could be because I was not using new-style classes, i.e. not inheriting from object in my class Foo. Changing that fixed it:
>>> import jsonpickle
>>> class Foo(object):
...     def __init__(self, bar, baz):
...             self._bar = bar
...             self._baz = baz
...     def show(self):
...             print "self._bar, self._baz =", self._bar, self._baz
>>> foo = Foo("a", "b")
self._bar, self._baz = a b
>>> foo_pickled = jsonpickle.encode(foo)
>>> foo_pickled
'{"py/object": "__main__.Foo", "_bar": "a", "_baz": "b"}'
>>> foo2 = jsonpickle.decode(foo_pickled)
self._bar, self._baz = a b
>>> foo == foo2
>>> type(foo) == type(foo2)

- Vasudev Ram - Dancing Bison Enterprises


Thomas K said...

At a guess, maybe it expects new style classes, i.e. inheriting from object? You're using an old style class, as type(foo) is instance.

Vasudev Ram said...

Thomas K:

You're right, thanks. I forgot; new-style classes have been around for a while now :) I've updated the post with a corrected example.