0

I am very new to python and need help to resolve below issue please,

I have to create python object named Error and then print it in json format: Below is the link to image of object structure enter image description here

Data class

class Data:

    def __init__(self,fileName:str, rowId:int, rowData:str):
        self.fileName = fileName
        self.rowId= rowId
        self.rowData = rowData

    def get_fileName(self):
        return self.fileName

    def set_fileName(self, fileName):
        self.fileName = fileName

    def get_rowId(self):
        return self.rowId

    def set_rowId(self, rowId):
        self.rowId = rowId

    def get_rowData(self):
        return self.rowData

    def set_rowData(self, rowData):
        self.rowData = rowData

Errors class:

from Process import Process 
from RootCause import RootCause
import json

class Errors(object):

    def __init__(self, process,rootCause):
        self.process= process
        self.rootCause= rootCause

    def get_process(self):
        return self.process

    def set_process(self, process):
        self.process = process

    def get_rootCause(self):
        return self.rootCause

    def set_rootCause(self, rootCause):
        self.rootCause = rootCause

    def __str__(self):
        return (json.dumps(self.process.get_flow))

Process class--

class Process:

    def __init__(self, id:str,flow:str,flowSubType:str):
        self.id= id
        self.flow= flow
        self.flowSubType= flowSubType

    def get_id(self):
        return self.id

    def set_id(self, id):
        self.id = id

    def get_flow(self):
        return self.flow

    def set_flow(self, flow):
        self.flow = flow

    def get_flowSubType(self):
        return self.flowSubType

    def set_flowSubType(self, flowSubType):
        self.flowSubType = flowSubType

RootCause class--

class RootCause:

    def __init__(self,system:str, code:str,message:str,timeStamp:str):
        self.system= system
        self.code= code
        self.message= message
        self.timeStamp= timeStamp

    def get_system(self):
        return self.system

    def set_system(self, system):
        self.system = system

    def get_code(self):
        return self.code

    def set_code(self, code):
        self.code = code

    def get_message(self):
        return self.message

    def set_message(self, message):
        self.message = message

    def get_timeStamp(self):
        return self.timeStamp

    def set_timeStamp(self, timeStamp):
        self.timeStamp = timeStamp

Error class:

from Data import Data
from Errors import Errors
from Process import Process
from RootCause import RootCause
from typing import List
import json

class Error(object):
    def __init__(self,data,errors : List[Errors]):
         self.data= data
         self.errors= errors

    def get_data(self):
        return self.data

    def set_data(self, data):
        self.data=data

    def get_errors(self):
        return self.errors

    def set_errors(self, errors):
        self.errors = errors

def test():
    data = Data('a',2,'b')
    process = Process('id','flow','subtype')
    rootCause = RootCause('sys','co','message','timestamp')
    errors = [process, rootCause]
    error = Error(data,errors)
    json_data = json.dumps(error, default=lambda o: o.__dict__)
    print(json_data)

test()

After executing Error class I m getting output as below:

{
"data": 
    {
       "fileName": "a",
       "rowId": 2,
       "rowData": "b"
    },
    "errors": [
        {
         "id": "id",
         "flow": "flow", 
         "flowSubType": "subtype"
        }, 
        {
         "system": "sys",
         "code": "co",
         "message": "message",
         "timeStamp": "timesta"
        }
    ]
}

But I want help in printing the output as below:

{
    "data": {
        "fileName": "a",
        "rowId": 2,
        "rowData": "b"
    },
    "errors": [
        {
            "Process": {
                "id": "id",
                "flow": "flow",
                "flowSubType": "subtype"
            },
            "error": {
                "system": "sys",
                "code": "co",
                "message": "message",
                "timeStamp": "timestamp"
            }
        }
    ]
}

Could someone please help me in this issue.

13
  • 2
    I'm going to first ask about all these getters and setters. Did you come to Python from Java? These are not needed. We can work with attributes directly in Python. Commented Apr 14, 2020 at 14:08
  • Second, please help me find where student is defined? I can't see what student is in this line: json_data = json.dumps(student, default=lambda o: o.__dict__) Commented Apr 14, 2020 at 14:10
  • What Neil says, plus this "one file per class" thingie is totally unpythonic. Commented Apr 14, 2020 at 14:11
  • @neil- question number 1 - yes i m a java developer , and i this is first time i am interacting with python. Question number 2- sorry for mentioning student , it should be error over there. I have edited it now.u can check it now. Commented Apr 14, 2020 at 14:18
  • @bruno - ohh.i see .i m not familiar with that concept actually. I was trying to implement it in the same way as in java..would u mind letting me know about what can be the best approach to this please?? Commented Apr 14, 2020 at 14:22

1 Answer 1

2

Two ways you could get the desired output

Method 1: Store the errors in a dictionary rather than a list:

class Error(object):
    def __init__(self,data,errors : List[Errors]):
         self.data= data
         self.errors= {"Process": errors[0], "errors": errors[1]}

Method 2 (recommended), write a proper asdict() function (using the Python data model is good practice where it makes sense, but the __dict__ dunder is a bit finicky and should only really be used to inspect objects, not to get a business-case formatted object representation.

class Error(object):
    def __init__(self,data,errors : List[Errors]):
         self.data= data
         self.errors= errors

    def asdict(self):
        return {
            "data": self.data.__dict__, # or you can write an asdict() on every class
            "errors": {"process": self.errors[0].__dict__, "error": self.errors[1].__dict__}
        }

You'd call this with:

d = obj.asdict()
json.dumps(d)  # will probably still need the default to handle those nested objects. unless you write asdict() methods on those too and call them above.

Regarding the one or two other points from my comments:

  • In Python we are allowed to access object attributes directly like obj.attr.

  • Getters and setters aren't needed.

  • If you don't want someone accessing a variable, prepend an underscore. eg self._data This doesn't actually do anything, but by convention Python coders know to leave underscore instance variables alone, or accept the consequences if they don't. So it is like a soft policy "private" variable.

  • If down the line you want a getter that actually does something (eg, converts from metric to imperial before returning), it is very easy to add this in with property decorators.

Sign up to request clarification or add additional context in comments.

1 Comment

this solution has worked. thank u so much for the detailed info , it helped me in getting some useful tips on python.

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.