Serializing Python Objects Into JSON

Overview:

  • JSON is an abbreviation of JavaScript Object Notation.
  • Though the name has "JavaScript" on it, JSON is a language independent data interchange format.
  • JSON is a text based data interchange format.
  • Any Python object can be serialized into JSON format and vice versa.
  • All popular programming languages support converting objects into JSON and vice versa.
  • Without involving any objects as well, JSON strings can be formed and interchanged between any two processes, client and server as data.
  • Several REST APIs and web services return data as JSON. Even the error messages from the REST APIs are returned as JSON strings.

 

Structure of a JSON string:

  • JSON structure is so simple.
  • A left square bracket starts an array and a right square bracket ends an array.
  • The left curly brace starts an object and right curly brace ends the object.
  • A colon separates a name and the value and a comma separates the name value pair.
  • A value in a JSON string could be an object represented as a JSON string, an array represented as a JSON string, a number or a string.
  • A JSON value can be any of the following constants as well: true, false, and null.

   

Encoding of Python Objects in JSON:

Encoding of simple python objects into JSON string

  • The python module json converts a python dict object into JSON objects, whereas the list and tuple are converted into JSON array.
  • A python str is converted into a JSON string.
  • Integers and floating-point numbers are converted into JSON numbers.
  • The Boolean value True is converted into JSON constant true.
  • The Boolean value False is converted into JSON constant false.
  • None, which represents a null in Python, is converted into JSON constant null.

 

Serializing any Python object into a JSON String:

Serializing any custom python object into a JSON string

  • If any other object type of Python apart from the ones listed above needs to be serialized into JSON format then the json.JSONEncoder should be subclassed and the default() method needs to be overridden.
  • Care must be taken to call the base-class version of the default() method to raise an exception when unsupported objects are passed in.
  • The subclass JSONEncoder can be instantiated and the encode() method can be called to get the JSON string.
  • Instead of sub-classing the JSONEncoder a serialization method can be defined.
  • The method name can be passed as the value for the keyword argument default for the functions dump and dumps.
  • In both of the ways described above the serializing method can return a dictionary,  list, array, str, int or float. The vars() method, which is one of the python built-in methods and the __dict__  attribute of the object are some of the utilities that can be used in implementing the serialization method.

 

Example1: Converting simple Python objects into JSON string

import json

 

# A dictionary of roll numbers vs student names

studentDict = {1:"John Napier",

               2:"Leonhard Euler",

               3:"Scarlett O'Hara",

               4:"Henry Ford"}

 

jsonString  = json.dumps(studentDict)

 

# A python dictionary as a JSON string

print(jsonString)

 

# A list as JSON

repDigits = [11,22,33,44]

jsonString  = json.dumps(repDigits)

 

# A python list as a JSON string

print(jsonString)

 

# Print None as JSON

reference1 = None

jsonString  = json.dumps(reference1)

print(jsonString)

 

# Print True as JSON

alive = True

jsonString  = json.dumps(alive)

print(jsonString)

Output:

{"1": "John Napier", "2": "Leonhard Euler", "3": "Scarlett O'Hara", "4": "Henry Ford"}

[11, 22, 33, 44]

null

true

 

Example2: Converting custome Python objects into json string by deriving from json.JSONEncoder

# Sample Python program for serializing an instance of a custom Python class as JSON string

from json import JSONEncoder

import json

 

# A class without JSON Serialization support

class Class_No_JSONSerialization:

        pass

 

# A class with JSON Serialization support

class MobilePhone:

    contacts = None

    apps     = None

   

    def __init__(self, contacts, apps):

        self.contacts   = contacts

        self.apps       = apps

   

    def startCall():

        pass

 

    def endCall():

        pass

 

# A specialised JSONEncoder that encodes MobilePhone

# objects as JSON

class MobilePhoneEncoder(JSONEncoder):

    def default(self, object):

        if isinstance(object, MobilePhone):

            return object.__dict__

        else:

            # call base class implementation which takes care of

            # raising exceptions for unsupported types

            return json.JSONEncoder.default(self, object)

 

# Create a mobile phone object       

contacts = {"xxx-xxx-xxxx": "Joe",

            "yyy-yyy-yyyy": "Joe",

            "zzz-zzz-zzzz": "Ane",

            "aaa-aaa-aaaa": "Rod",

            }

apps     = ["facebook",

            "linkedin",

            "twitter"]

 

myMobile        = MobilePhone(contacts, apps)

 

# Use the MobilePhoneEncoder to decode a MobilePhone object

jsonString      = MobilePhoneEncoder().encode(myMobile)

print(jsonString)

 

# Decoding an unsupported type into JSON

jsonString1     = MobilePhoneEncoder().encode(Class_No_JSONSerialization())

 

# Will raise an exception

print(jsonString1)

 

Output:

{"contacts": {"xxx-xxx-xxxx": "Joe", "yyy-yyy-yyyy": "Joe", "zzz-zzz-zzzz": "Ane", "aaa-aaa-aaaa": "Rod"}, "apps": ["facebook", "linkedin", "twitter"]}

 

Traceback (most recent call last):

  File "jsonex1.py", line 51, in <module>

    jsonString1     = MobilePhoneEncoder().encode(Class_No_JSONSerialization())

  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 199, in encode

    chunks = self.iterencode(o, _one_shot=True)

  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 257, in iterencode

    return _iterencode(o, 0)

  File "jsonex1.py", line 32, in default

    return json.JSONEncoder.default(self, object)

  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 180, in default

    o.__class__.__name__)

TypeError: Object of type 'Class_No_JSONSerialization' is not JSON serializable


Copyright 2020 © pythontic.com