On Dec 18, 11:30 pm, Peter Otten <__pete...@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. -- http://mail.python.org/mailman/listinfo/python-list