534

I want to convert JSON data into a Python object.

I receive JSON data objects from the Facebook API, which I want to store in my database.

My current View in Django (Python) (request.POST contains the JSON):

response = request.POST
user = FbApiUser(user_id = response['id'])
user.name = response['name']
user.username = response['username']
user.save()
  • This works fine, but how do I handle complex JSON data objects?
  • Wouldn't it be much better if I could somehow convert this JSON object into a Python object for easy use?
6
  • Typically JSON gets converted to vanilla lists or dicts. Is that what you want? Or are you hoping to convert JSON straight to a custom type? Commented Jul 5, 2011 at 7:05
  • I want to convert it into an object, something I can access using the "." . Like from the above example -> reponse.name, response.education.id etc.... Commented Jul 5, 2011 at 7:09
  • 89
    Using dicts is a weak-sauce way to do object-oriented programming. Dictionaries are a very poor way to communicate expectations to readers of your code. Using a dictionary, how can you clearly and reusably specify that some dictionary keys-value pairs are required, while others aren't? What about confirming that a given value is in the acceptable range or set? What about functions that are specific to the type of object you are working with (aka methods)? Dictionaries are handy and versatile, but too many devs act like they forgot Python is an object oriented language for a reason. Commented Apr 15, 2016 at 16:20
  • 3
    There is a python library for this github.com/jsonpickle/jsonpickle (commenting since answer is too below in the thread and wont be reachable.) Commented May 10, 2019 at 4:55
  • I don't think anybody has forgotten that Python is object-oriented but that would be a wonderful development. There is a reason why so many functional languages are vastly superior to OOP in so many cases. If you can manage to use stateless functions and immutable data structures you'll be better off. OOP never was the be-all-and-end-all of computing languages. Commented Mar 15, 2023 at 14:36

32 Answers 32

1
2
0

Here is my way.

Features

  • support type hints
  • raise error if key is missing.
  • skip extra value in data
import typing

class User:
    name: str
    age: int

    def __init__(self, data: dict):
        for k, _ in typing.get_type_hints(self).items():
            setattr(self, k, data[k])

data = {
    "name": "Susan",
    "age": 18
}

user = User(data)
print(user.name, user.age)

# Output: Susan 18
Sign up to request clarification or add additional context in comments.

Comments

0

Using python 3.7, I find the following quite simple and effective. In this case, loading JSON from a file into a dictionary:

class Characteristic:
    def __init__(self, characteristicName, characteristicUUID):
        self.characteristicName = characteristicName
        self.characteristicUUID = characteristicUUID


class Service:
    def __init__(self, serviceName, serviceUUID, characteristics):
        self.serviceName = serviceName
        self.serviceUUID = serviceUUID
        self.characteristics = characteristics

class Definitions:
    def __init__(self, services):
        self.services = []
        for service in services:
            self.services.append(Service(**service))


def main():
    parser = argparse.ArgumentParser(
        prog="BLEStructureGenerator",
        description="Taking in a JSON input file which lists all of the services, "
                    "characteristics and encoded properties. The encoding takes in "
                    "another optional template services and/or characteristics "
                    "file where the JSON file contents are applied to the templates.",
        epilog="Copyright Brown & Watson International"
    )

    parser.add_argument('definitionfile',
                        type=argparse.FileType('r', encoding='UTF-8'),
                        help="JSON file which contains the list of characteristics and "
                             "services in the required format")
    parser.add_argument('-s', '--services',
                        type=argparse.FileType('r', encoding='UTF-8'),
                        help="Services template file to be used for each service in the "
                             "JSON file list")
    parser.add_argument('-c', '--characteristics',
                        type=argparse.FileType('r', encoding='UTF-8'),
                        help="Characteristics template file to be used for each service in the "
                             "JSON file list")

    args = parser.parse_args()
    definition_dict = json.load(args.definitionfile)
    definitions = Definitions(**definition_dict)

Comments

1
2

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.