1

I am having a problem I can't quite seem to find the solution to. I have an application that speaks with a Java app via JSON. Pretty simple, but I'm having an issue decoding JSON off the wire with nested objects. For example I have:

class obj1(object):
    def __init__(self, var1, var2):
        self.var1 = var1
        self.var2 = var2

    def __eq__(self, other):
      return (isinstance(other, obj1) and
        self.var1 == obj1.var1 and
        self.var2 == obj2.var2)

class obj2(object):
    def __init__(self, v1, v2, obj1):
        self.v1 = v1
        self.v2 = v2
        self.obj1 = obj1

and I want to serialize and de-serialize the "obj2" class, I can create it pretty easily:

myObj1 = obj1(1,2)
myObj2 = obj2(3.14, 10.05, myObj1)

when I want to send it Json, it's obviously pretty easy:

import json

def obj_to_dict(obj):
    return obj.__dict__

my_json = json.dumps(myObj2, default=obj_to_dict)

this creates the perfect JSON as I would expect:

{"obj1": {"var1": 1, "var2": 2}, "v1": 3.14, "v2": 10.05}

the problem I am having is encoding this string back into the two objects. I can't add any extra type information because the application that sends this schema back sends it back in exactly this way. so when I try and rebuild it from the dictionary:

obj_dict = json.loads(my_json)
myNewObj = obj2(**obj_dict)

it doesn't quite work

print myNewObj.obj1 == obj1  #returns False.

Is there some better way to get from JSON -> Custom objects? (In reality I have like 20 custom objects nested inside another Object. the Object -> JSON works perfectly, its just going the other direction. Any thoughts?

2
  • Have you tried adding debug output in def __eq__(self, other): ? Commented Nov 11, 2015 at 17:41
  • yes, basically what happens myNewObj.obj1 is a dictionary of the attributes and never gets instantiated into an "obj1" object with the right parameters. Commented Nov 11, 2015 at 17:46

2 Answers 2

2

You need to "chain" the object creation.

class obj2(object): def __init__(self, v1, v2, obj1): self.v1 = v1 self.v2 = v2 if type(obj1) is dict: self.obj1 = obj1(**obj1) else: self.obj1 = obj1

Sign up to request clarification or add additional context in comments.

Comments

0

I have a slightly different approach which uses inheritance:

class json_dict(object):
    def __init__(self, **kargs):
        self.dict = { k:kargs[k] for k in kargs.keys() }

    @property
    def json(self):
        d = self.dict
        return str({k:(d[k].dict if isinstance(d[k], json_dict) else d[k]) for k in d.keys()})


class obj1(json_dict):
    def __init__(self, var1, var2):
        super(obj1, self).__init__(var1=var1, var2=var2)  # dict at obj1 level

    def __eq__(self, other):
      return (isinstance(other, json_dict)) and (self.dict == other.dict)

class obj2(json_dict):
    def __init__(self, v1, v2, **kobjs):
        super(obj2, self).__init__(v1=v1, v2=v2)  # dict at obj2 level

        for k, obj in kobjs.iteritems():
            if isinstance(obj, json_dict):
                self.dict[k] = obj  # append as many objects as you need

With this approach, you can init obj1 and obj2 as followings:

myobj1 = obj1("obj1 variable 1","obj1 variable 2")
myobj2 = obj2("obj2 variable 1","obj2 variable 2", obj1=myobj1)

appendedmore = obj2("obj2 variable 1","obj2 variable 2", obj1=o1, obj2=o2, obj3=o3)  # o1,o2,o3 must inherit from json_dict

# get json string from the objects
myobj1.json  # "{'var1': 'obj1 variable 1', 'var2': 'obj1 variable 2'}"
myobj2.json  # "{'obj1': {'var1': 'obj1 variable 1', 'var2': 'obj1 variable 2'}, 'v1': 'obj2 variable 1', 'v2': 'obj2 variable 2'}"

Sorry if my code looks clunky! Please advice if have any suggestions!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.