Python serialize objects list to JSON
Question: I am trying to serialize to JSON the `__dict__` of an object, which is working
fine, until I append objects to one of the instance attribute of my first
object:

    
    
    from json import dumps
    
    class A(object):
        def __init__(self):
            self.b_list = []
    
    class B(object):
        def __init__(self):
            self.x = 'X'
            self.y = 'Y'
        def __repr__(self):
            return dumps(self.__dict__)
    
    a = A()
    
    print dumps(a.__dict__)  # works fine
    
    a.b_list.append(B())
    
    print dumps(a.__dict__)
    

When calling for the second time `dumps`, I got the following `TypeError`:

    
    
    TypeError: {"y": "Y", "x": "X"} is not JSON serializable
    

I don't understand why I keep getting this error while I can't see why this is
not serializable to JSON.


Answer: That's because instances of `B` are not a simple type. Because you gave `B` a
`__repr__` method, the instance is _printed_ as it's JSON representation, but
it is not itself a supported JSON type.

Remove the `__repr__` method and the traceback is much less confusing:

    
    
    >>> class A(object):
    ...     def __init__(self):
    ...         self.b_list = []
    ... 
    >>> class B(object):
    ...     def __init__(self):
    ...         self.x = 'X'
    ...         self.y = 'Y'
    ... 
    >>> a = A()
    >>> a.b_list.append(B())
    >>> 
    >>> print dumps(a.__dict__)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/json/__init__.py", line 243, in dumps
        return _default_encoder.encode(obj)
      File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/json/encoder.py", line 207, in encode
        chunks = self.iterencode(o, _one_shot=True)
      File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/json/encoder.py", line 270, in iterencode
        return _iterencode(o, 0)
      File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/json/encoder.py", line 184, in default
        raise TypeError(repr(o) + " is not JSON serializable")
    TypeError: <__main__.B object at 0x10a753e10> is not JSON serializable
    

Use the `default` keyword argument to encode custom objects:

    
    
    def encode_b(obj):
        if isinstance(obj, B):
            return obj.__dict__
        return obj
    
    json.dumps(a, default=encode_b)
    

Demo:

    
    
    >>> def encode_b(obj):
    ...     if isinstance(obj, B):
    ...         return obj.__dict__
    ...     return obj
    ... 
    >>> dumps(a.__dict__, default=encode_b)
    '{"b_list": [{"y": "Y", "x": "X"}]}'
    

