83

I need to know how to convert a dynamic python object into JSON. The object must be able to have multiple levels object child objects. For example:

class C(): pass
class D(): pass

c = C()
c.dynProperty1 = "something"
c.dynProperty2 = { 1, 3, 5, 7, 9 }
c.d = D()
c.d.dynProperty3 = "d.something"

# ... convert c to json ...

I tried this code:

import json
 
class C(): pass
class D(): pass
 
c = C()
c.what = "now?"
c.now = "what?"
c.d = D()
c.d.what = "d.what"
 
json.dumps(c.__dict__)

but I got an error that says TypeError: <__main__.D instance at 0x99237ec> is not JSON serializable.

How can I make it so that any sub-objects that are classes are automatically serialized using their __dict__?

6
  • except for the dynamic element--I don't know what properties might be added to the object before it is serialized into json. Commented Sep 13, 2011 at 21:34
  • You'll notice the solution of the duplicate works in your case, too. Commented Sep 13, 2011 at 21:45
  • @phihag: thanks for pointing that out. It helped me realize there was more to my question than I thought (see updated question). Commented Sep 13, 2011 at 22:05
  • Then you should probably ask a new question. Pay special notice not to include invalid example code. For example, you want class C(object): pass. I added an answer that should solve your problem. Commented Sep 13, 2011 at 22:56
  • 3
    Oops sorry, I was totally wrong. class C(): pass is of course valid, but it creates an old-style class (just like class C: pass would) in Python 2.x. old-style classes are strange beasts. By inheriting from object, you get the saner new-style behaviour. Commented Sep 14, 2011 at 8:11

4 Answers 4

150

Specify the default= parameter (doc):

json.dumps(c, default=lambda o: o.__dict__)
Sign up to request clarification or add additional context in comments.

8 Comments

One of my object's attributes is a datetime and i'm having 'AttributeError' object has no attribute '__dict__'
@arun For a set, you'd use a different method. If you expect both objects and set, use a helper function instead of a lambda, test for isinstance(o, set) and then return something like list(o).
This one workds better than json.dumps(c.__dict__), why?
@soulmachine your code just dumps a dictionary, whose values (and values of values, recursively) may still be Python objects that have no JSON representation. The code in this answer uses the object's __dict__ for all those problematic objects, recursively.
@soulmachine From the Python3 documentation: If specified, default should be a function that gets called for objects that can’t otherwise be serialized. It should return a JSON encodable version of the object or raise a TypeError. If not specified, TypeError is raised.
|
18
json.dumps(c.__dict__)

That will give you a generic JSON object, if that's what you're going for.

2 Comments

After looking into phihag's comment, I did some further testing and realized that this solution does not work in all cases...updating question...
That works for me as well.
9

Try using this package python-jsonpickle

Python library for serializing any arbitrary object graph into JSON. It can take almost any Python object and turn the object into JSON. Additionally, it can reconstitute the object back into Python.

Comments

0

json.dumps expects a dictonary as a parameter. For an instance c, the attribute c.__dict__ is a dictionary mapping attribute names to the corresponding objects.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.