Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting Nested Json into Python object

Tags:

python

json

I have nested json as below

{
"product" : "name",
"protocol" : "scp",
"read_logs" : {
    "log_type" : "failure",
    "log_url" : "htttp:url"
    }
}

I am trying to create Python class object with the below code.

import json
class Config (object):
    """
    Argument: JSON Object from the configuration file.
    """
   def __init__(self, attrs):
        if 'log_type' in attrs:
            self.log_type = attrs['log_type']
            self.log_url = attrs['log_url']
        else:
           self.product = attrs["product"]
           self.protocol = attrs["protocol"]
   def __str__(self):
       return "%s;%s" %(self.product, self.log_type)

   def get_product(self):
        return self.product

   def get_logurl(self):
       return self.log_url

class ConfigLoader (object):
    '''
        Create a confiuration loaded which can read JSON config files
    '''
    def load_config (self, attrs):
        with open (attrs) as data_file:
            config = json.load(data_file, object_hook=load_json)
        return config

def load_json (json_object):
    return Config (json_object)

loader = ConfigLoader()
config = loader.load_config('../config/product_config.json')

print config.get_protocol()

But, the object_hook is invoking the load_json recursively and the Class Config init is being called twice. So the final object that I created does not contain the nested JSON data.

Is there any way to read the entire nested JSON object into a single Python class ?

Thanks

like image 697
Praveen Avatar asked May 04 '17 07:05

Praveen


People also ask

What converts .JSON file into a Python object?

Use jsonpickle module to convert JSON data into a custom Python Object. jsonpickle is a Python library designed to work with complex Python Objects. You can use jsonpickle for serialization and deserialization complex Python and JSON Data.

How do you parse nested JSON objects in Python?

Start by importing the json library. We use the function open to read the JSON file and then the method json. load() to parse the JSON string into a Python dictionary called superHeroSquad. That's it!

How do you serialize nested JSON in Python?

For serializing and deserializing of JSON objects Python “__dict__” can be used. There is the __dict__ on any Python object, which is a dictionary used to store an object's (writable) attributes. We can use that for working with JSON, and that works well.

How do I convert JSON to Python?

Parse JSON - Convert from JSON to Python If you have a JSON string, you can parse it by using the json. loads() method. The result will be a Python dictionary.


2 Answers

A variation on Pankaj Singhal's idea, but using a "generic" namespace class instead of namedtuples:

import json

class Generic:
    @classmethod
    def from_dict(cls, dict):
        obj = cls()
        obj.__dict__.update(dict)
        return obj

data = '{"product": "name", "read_logs": {"log_type": "failure", "log_url": "123"}}'

x = json.loads(data, object_hook=Generic.from_dict)
print(x.product, x.read_logs.log_type, x.read_logs.log_url)
like image 58
AKX Avatar answered Nov 15 '22 05:11

AKX


namedtuple & object_hook can help create a one-liner:

# Create an object with attributes corresponding to JSON keys.
def json_to_obj(data): return json.loads(data, object_hook=lambda converted_dict: namedtuple('X', converted_dict.keys())(*converted_dict.values()))

OR Create a more readable function like below:

def _object_hook(converted_dict): return namedtuple('X', converted_dict.keys())(*converted_dict.values())
def json_to_obj(data): return json.loads(data, object_hook=_object_hook)

Below is the code snippet to use it:

import json
from collections import namedtuple

data = '{"product": "name", "read_logs": {"log_type": "failure", "log_url": htttp:url}}'

x = json_to_obj(data)
print x.product, x.read_logs.log_type, x.read_logs.log_url

NOTE: Check out namedtuple's rename parameter.

like image 44
Pankaj Singhal Avatar answered Nov 15 '22 03:11

Pankaj Singhal