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

Discussion in 'Python' started by shearichard, Dec 18, 2010.

  1. shearichard

    shearichard Guest

    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 .

    Richard.
     
    shearichard, Dec 18, 2010
    #1
    1. Advertising

  2. shearichard

    Peter Otten Guest

    Re: Serialize my class as JSON causes "__init__() got an unexpectedkeyword argument 'indent'" ?

    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()
     
    Peter Otten, Dec 18, 2010
    #2
    1. Advertising

  3. shearichard

    shearichard Guest

    Re: Serialize my class as JSON causes "__init__() got an unexpectedkeyword argument 'indent'" ?

    On Dec 18, 11:30 pm, Peter Otten <> 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.
     
    shearichard, Dec 18, 2010
    #3
  4. shearichard

    Terry Reedy Guest

    Re: Serialize my class as JSON causes "__init__() got an unexpectedkeyword argument 'indent'" ?

    On 12/18/2010 6:32 AM, shearichard wrote:

    > 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
     
    Terry Reedy, Dec 18, 2010
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Gordz
    Replies:
    3
    Views:
    3,973
    John Oakes
    Jun 7, 2004
  2. Florian Frank
    Replies:
    0
    Views:
    259
    Florian Frank
    Jun 30, 2009
  3. sajuptpm
    Replies:
    2
    Views:
    374
    sajuptpm
    Dec 28, 2012
  4. Acácio Centeno
    Replies:
    1
    Views:
    302
    dieter
    Feb 15, 2013
  5. Bryan Britten
    Replies:
    9
    Views:
    286
    Bryan Britten
    May 28, 2013
Loading...

Share This Page