6

The problem described in this question was caused by a dumb mistake made while I was experimenting with ways to fix it, namely not reverting a change made after testing it -- however the site won't allow let me to delete it. So I suggest you save yourself some time better spent elsewhere by ignoring it.

While trying out an answer that initially suggested using a custom JSONEncoder subclass to solve a printing problem, I discovered that what the documentation suggests doing in the Extending JSONEncoder: section does not appear to work. Here's my code which is patterned after the ComplexEncoder example also in that section of the docs.

import json

class NoIndent(object):
    def __init__(self, value):
        self.value = value

class MyEncoder(json.JSONEncoder):
    def default(self, obj):
        print 'MyEncoder.default() called'
        if isinstance(obj, NoIndent):
            return 'MyEncoder::NoIndent object'  # hard code string for now
        else:
            return json.JSONEncoder.default(self, obj)

data_structure = {
    'layer1': {
        'layer2': {
            'layer3_1': NoIndent([{"x":1,"y":7},{"x":0,"y":4},{"x":5,"y":3},{"x":6,"y":9}]),
            'layer3_2': 'string'
        }
    }
}

print json.dumps(data_structure, default=MyEncoder)

And this is the traceback that results:

Traceback (most recent call last):
  File "C:\Files\PythonLib\Stack Overflow\json_parsing.py", line 26, in <module>
    print json.dumps(data_structure, default=MyEncoder)
  File "E:\Program Files\Python\lib\json\__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "E:\Program Files\Python\lib\json\encoder.py", line 201, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "E:\Program Files\Python\lib\json\encoder.py", line 264, in iterencode
    return _iterencode(o, 0)
RuntimeError: maximum recursion depth exceeded
martineau
  • 119,623
  • 25
  • 170
  • 301

1 Answers1

20

The docs say:

To use a custom JSONEncoder subclass (e.g. one that overrides the default() method to serialize additional types), specify it with the cls kwarg; otherwise JSONEncoder is used.

print json.dumps(data_structure, cls=MyEncoder)

yields

{"layer1": {"layer2": {"layer3_2": "string", "layer3_1": "MyEncoder::NoIndent object"}}}
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • Oops, I just noticed that myself :$. It's was that way originally but I changed it while doing some experimenting and forgot to put it back. Thanks. – martineau Nov 06 '12 at 14:02