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 .
Richard.
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)
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.
> 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 !
If you have any idea who to improve that part of the doc so you would
have understood it without Peter's nice explanation and example here,
please open a doc issue on the tracker.
--
Terry Jan Reedy