Retro
Retro

Reputation: 130

Decoding Objects from JSON in python

I have a class that looks like this:

class Car:
def __init__(self, name, colour, wheels):
    self.name = name
    self.colour = colour
    self.wheels = wheels

I would like to create objects of the above class from the JSON file, which looks like this but with many entries:

  "Cars":[
  {
  "name": "Golf",
  "colour": "red",
  "wheels": 4,
  },
  {
  "name": "Up",
  "colour": "green",
  "wheels": 3,
  }
  ]

And then add them to a dictionary with the layout {"name":object}. I've looked at the different tutorials and examples available, but most seems to be about dumping objects, not pulling them out and recreating objects from them.

Upvotes: 1

Views: 814

Answers (2)

opatut
opatut

Reputation: 6864

import json

class Car(object):
    def __init__(self, name, colour, wheels):
        self.name = name
        self.colour = colour
        self.wheels = wheels

    def __repr__(self):
        return 'A {} {} with {} wheels'.format(self.colour, self.name, self.wheels)

raw = '{"name": "Ferrari", "colour": "red", "wheels": 4}'
decoded = json.loads(raw)
car = Car(**decoded)
print(car)

You can use the ** syntax to turn a dictionary into named parameters. Basically it transforms to a call like this: Car(name="Ferrari", colour="red", wheels="4"). So you don't need to worry about the order.

If you have a list, you can of course map over the JSON result:

raw = '[{...}, {...}]'
decoded = json.loads(raw)
cars = [Car(**d) for d in decoded]
print(cars)

Upvotes: 1

Fabiano
Fabiano

Reputation: 377

If your file ensures that you have aways same order (name, colour, wheels) and same size (3 items), you can use something like this:

JSON file (foo.json):

{"Cars":{
"Golf":{
  "name": "Golf",
  "colour": "red",
  "wheels": 4
  },  
"Robin": {
  "name": "Up",
  "colour": "green",
  "wheels": 3
  }
  } 
}


>>> import json
>>> import collections
>>> data = ''.join(i.replace('\n','') for i in open('foo.json').readlines())
>>> decoder = json.JSONDecoder(object_pairs_hook=collections.OrderedDict)
>>>
>>> class Car(object):
...  def __init__(self, name, colour, wheels):
...     self.name = name
...     self.colour = colour
...     self.wheels = wheels
... 
>>> j = decoder.decode(data)
>>> 
>>> out_dict = {car:Car(*j['Cars'][car].values()) for car in j['Cars']}
>>>
>>> golf = out_dict['Golf']
>>> golf.name
u'Golf'
>>> golf.colour
u'red'
>>> golf.wheels
4

Upvotes: 1

Related Questions