Serialize my class as JSON causes "__init__() got an unexpected keyword argument 'indent'" ?

shearichard shearichard at gmail.com
Sat Dec 18 06:32:29 EST 2010


On Dec 18, 11:30 pm, Peter Otten <__pete... at web.de> wrote:
> shearichard wrote:
> > Hi - I've got a straightforward class I want to serialize as JSON
> > (actually I want to a serialize a list of them but I believe that's
> > irrelevant).
>
> > I've subclassed JSONEncoder and defined my own version of the
> > 'default' method ( based upon what I read at
> >http://docs.python.org/library/json.html) but when I then try to
> > serialize the class I get the (fairly weird) error message : "TypeError:
> > __init__() got an unexpected keyword argument 'indent'".
>
> > I suspect I'm doing something pretty fundamentally wrong but I don't
> > know what - can anyone tell me what's wrong (or alternatively tell me
> > how to log this as a bug ;-)
>
> > Here's my test case :
>
> > import json
> > class SuperPeople(object):
> >     pass
> > class People(SuperPeople, json.JSONEncoder):
> >     def __init__(self, name, age):
> >         self.__name = name
> >         self.__age = age
> >     def default(self, obj):
> >         if isinstance(obj, People):
> >             return [obj.__name, obj.__age]
> >         else:
> >             return json.JSONEncoder.default(self, obj)
>
> > def main():
> >     lstPeople = []
> >     lstPeople.append(People("Mary", 50))
> >     lstPeople.append(People("Joe", 40))
> >     lstPeople.append(People("Sue", 30))
>
> >     print json.dumps(lstPeople, cls=People)
>
> > if __name__ == "__main__":
> >     main()
>
> > ... and this is what the stacktrace looks like  ....
>
> > Traceback (most recent call last):
> >   File "testJSON.py", line 24, in <module>
> >     main()
> >   File "testJSON.py", line 20, in main
> >     json.dumps(lstPeople, cls=People)
> >   File "C:\bin\installed\Python2.6\lib\json\__init__.py", line 237, in
> > dumps
> >     **kw).encode(obj)
> > TypeError: __init__() got an unexpected keyword argument 'indent'
>
> > ... I'm running Python 2.6 on Win32.
>
> > All suggestions welcomed .
>
> You pass the encoder *class* to json.dumps(), so the function has to
> instantiate it. It does that with the arguments that an encoder class must
> accept. There's no way for it to expect that an encoder requires a name and
> an age.
>
> The solution is to separate the encoder and the class that shall be encoded.
> Here's one way:
>
> import json
>
> class People(object):
>     def __init__(self, name, age):
>         self.__name = name
>         self.__age = age
>     def get_json_state(self):
>         return [self.__name, self.__age]
>
> class PeopleEncoder(json.JSONEncoder):
>     def default(self, obj):
>         if isinstance(obj, People):
>             return obj.get_json_state()
>         else:
>             return json.JSONEncoder.default(self, obj)
>
> def main():
>     lstPeople = []
>     lstPeople.append(People("Mary", 50))
>     lstPeople.append(People("Joe", 40))
>     lstPeople.append(People("Sue", 30))
>
>     print json.dumps(lstPeople, cls=PeopleEncoder)
>
> if __name__ == "__main__":
>     main()

Brilliant - thank you very much.

Now that you've explained it I can see why the documentation is
written the way it is ! Before I saw your example I thought the
documentation was a bit strange but I can see now what it was trying
to tell me !

Your help is much appreciated.

Richard.




More information about the Python-list mailing list