0

I am new to Python and learning python. I have a requirement where I need to convert Python object to Json String and Json String to Python object just like what we do in Jackson in Java. I am able to convert to Json String but while converting from json String to Python object, I am getting the following error.

AttributeError: 'dict' object has no attribute 'firstName'

I provide below the code details.

Employee Object as

import json

class Employee:

    def __init__(self):
        self._firstName = None
        self._lastName = None
        self._country = None

    @property
    def firstName(self):
        return self._firstName

    @firstName.setter
    def firstName(self, fName):
        self._firstName = fName

    @property
    def lastName(self):
        return self._lastName

    @lastName.setter
    def lastName(self, lName):
        self._lastName = lName

    @property
    def country(self):
        return self._country

    @country.setter
    def country(self, contryObj):
        self._country = contryObj

    def toJSON(self):
        return json.dumps(self, default=lambda o: o.__dict__,
                          sort_keys=True, indent=4)

    def toEmployee(self, jsonString):
        return json.loads(jsonString)

Country Object as

class Country:
    def __init__(self):
        self._countryName = None
        self._countryCode = None

    @property
    def countryName(self):
        return self._countryName

    @countryName.setter
    def countryName(self, cName):
        self._countryName = cName

    @property
    def countryCode(self):
        return self._countryCode

    @countryCode.setter
    def countryCode(self, cCode):
        self._countryCode = cCode

My test program is given below.

from toFromJson.Employee import Employee
from toFromJson.Country import Country


def checkEmp():
    emp = Employee()
    emp._firstName = "DD"
    emp._lastName = "Mishra"
    country = Country()
    country.countryCode = "12345"
    country.countryName = "India"
    emp.country = country

    print("Emp in toString format : ", emp.__dict__)
    print("--------------------- IN JSON -----------------")
    print(emp.toJSON())

    jsonString = '{ "_country": { "_countryCode": "7896", "_countryName": "India" }, "_firstName": "John", "_lastName": "Abrham" }'

    emp1 = emp.toEmployee(jsonString)
    print("Employee Name : ", emp1.firstName())
    print("Conveted object : ", emp1.__dict__)


if __name__ == "__main__":
    checkEmp()

What is the problem with this above code ? Please help me solve this. Besides I have few questions.

  1. Is there any framework in Python just like Jackson in Java to and from conversion ?
  2. How to achieve like @PropertyOrder("firstName","lastName","Country" ...etc) just like Jackson in java equivalent in python ?

Before posting this question, I have also gone through the following stackoverflow link How to make a class JSON serializable.

5
  • 1
    All your properties are not necessary, just use normal attributes. Commented Apr 20, 2019 at 16:50
  • Could please suggest, I have written like how we do in java with getter & setter. Commented Apr 20, 2019 at 16:52
  • Also put everything in one file; one class per file is Java-only, too. Commented Apr 20, 2019 at 16:56
  • Ok, accepted Sir, could please help me to solve this problem ? Commented Apr 20, 2019 at 16:57
  • You are calling emp1.firstName(), but emp1 is not Employee object. It simply stores the converted json, and hence its a dictionary. You need to call as emp.firstName(), but this won't serve your expected purpose. Have a look at stackoverflow.com/questions/10252010/… Commented Apr 20, 2019 at 17:44

1 Answer 1

1

You have to define hooks for json.loads and json.dumps:

import json

class Employee:
    def __init__(self, firstName=None, lastName=None, country=None):
        self.firstName = firstName
        self.lastName = lastName
        self.country = country

class Country:
    def __init__(self, countryName=None, countryCode=None):
        self.countryName = countryName
        self.countryCode = countryCode

def to_json(obj):
    if isinstance(obj, Employee):
        return {
            'firstName': obj.firstName,
            'lastName': obj.lastName,
            'country': obj.country,
        }
    if isinstance(obj, Country):
        return {
            'countryName': obj.countryName,
            'countryCode': obj.countryCode,
        }
    raise TypeError

def from_json(obj):
    if 'firstName' in obj:
        return Employee(**obj)
    if 'countryName' in obj:
        return Country(**obj)
    return obj

def check_emp():
    emp = Employee("DD", "Mishra", Country("India", "12345"))
    json_string = json.dumps(emp, default=to_json, sort_keys=True, indent=4)
    print(json_string)
    emp1 = json.loads(k, object_hook=from_json)
    print("Employee Name : ", emp1.firstName)

if __name__ == "__main__":
    check_emp()
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Daniel, I got to learn a lot from you. Could you please explain Employee(**obj). I did not get it. Is it something like varargs in Java ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.