Tuesday, 15 July 2014

How to correctly transform JSON into Python objects? -



How to correctly transform JSON into Python objects? -

i want parse json web service object structure. therefore, implementing subclass of json.jsondecoder object_hook method. haven't found way, yet, select right class given data. classes have same attributes, seems impossible identify right one, since require know key. let's have @ example:

i have next classes:

class post: def __init__(self, title, user=none, group=none): self.title = title self.user = user self.group = grouping class group: def __init__(self, name): self.name = name class user: def __init__(self, name): self.name = name

observe group , user class have same attributes. jsondecoder looks this:

class jsondecoder(json.jsondecoder): def __init__(self, encoding="utf-8"): json.jsondecoder.__init__(self, object_hook=self.dict_to_object) def dict_to_object(self, d): if "posts" in d: homecoming d["posts"] if "title" in d: if "user" in d: homecoming post(d["title"], user=d["user"]) if "group" in d: homecoming post(d["title"], group=d["group"]) if "name" in d: # how decide if user(d["name"]) or group(d["name")? homecoming none homecoming none

when sees dictionary containing key "name", can not decide whether create group or user object (hence homecoming none @ moment).

the json string parse looks following:

s = """ { "posts" : [ {"title" : "hello world", "user" : {"name" : "uli"}}, {"title" : "hello group", "group" : {"name" : "workgroup"}} ] } """

this should result in list of post objects, each having title , grouping or user.

how can solved in best way? accumulation of if-statements in dict_to_object way go? (the actual code looks much messier because of complext nested json structure.) or there other patterns or libraries should use? (though prefer go standard library.)

in case, , ime json decoding, best assign generic dict @ decode time, don't utilize object_hook, , defer creating individual typed objects until sec pass after decoding, when can arbitrarily inspect stream , hierarchy you're dealing with, i.e. object parent/child/sibling of what. (like @brenbam says)

use classmethod make_xyz functions, not constructors

object_hook looks seductive thing want. because it's there, it's wrong choice. it's ever right selection if can know 100% sure class utilize each object (and then, if easy evaluate without passing state around, i.e. writing ad-hoc parser within object-hook), typically elements follow order, json never malformed etc.

here hitting generic issue: in specific case constructor seeing {"name" : "xyz"} can't know type of json object is, parent object saw "user"/"group" : can. 1 solution refactor classes , constructors classmethods make_group(),make_user(). that's lumping second-decode-pass first-decode-pass, no particular reason, giving 1 giant brittle object_hook function. ime that's idea.

python json json-deserialization

No comments:

Post a Comment