Home > Software design >  Python - Can I convert an object containing objects into a dictionary?
Python - Can I convert an object containing objects into a dictionary?

Time:11-28

For example -

class Object:
    def __init__(self, string):
        self.string = string
 
class example:
    def __init__(self):
        self.obj = Object('hello')

and output should be -

{
    'obj' : {
        'string': 'hello'
    }
}

I know I can do it with for loops and __ dict __, but it becomes difficult when there are too many objects to handle.

Is there a way to do this in one or two lines?

CodePudding user response:

If you are willing to use the dataclasses-json library and dataclasses you could to something like this:

from dataclasses_json import dataclass_json

@dataclass_json
@dataclasses.dataclass
class InnerClass:
    foo: int
    bar: str

   
@dataclass_json
@dataclasses.dataclass
class OuterClass:
    inner: InnerClass

and then you will be able to use the to_dict and to_json methods:


>>> obj = OuterClass(InnerClass(foo=1, bar="some string"))
>>> obj.to_dict()
{'inner': {'foo': 1, 'bar': 'some string'}}
>>> obj.to_json()
'{"inner": {"foo": 1, "bar": "some string"}}'

CodePudding user response:

I like dataclasses-json approach, but here's similar approach using the dataclass-wizard library. This is likewise a serialization framework built in top of dataclasses, with a few notable differences; for instance, note that we don't need to decorate or subclass the inner dataclass in this case.

from __future__ import annotations

from dataclasses import dataclass

from dataclass_wizard import JSONWizard


@dataclass
class OuterClass(JSONWizard):
    inner: InnerClass


@dataclass
class InnerClass:
    foo: int
    bar: str

# serialize instance
obj = OuterClass(InnerClass(foo=1, bar="some string"))
obj.to_dict()
# {'inner': {'foo': 1, 'bar': 'some string'}}

You will note that output is exactly the same in this case.

Alternate Solutions

Other option can be to use dataclasses.asdict to convert instance to dict object. Also you can use json.dumps and pass default parameter if you want to serialize instance to a JSON string directly. Both options are shown below.

import json
from dataclasses import dataclass, asdict


@dataclass
class OuterClass:
    inner: 'InnerClass'


@dataclass
class InnerClass:
    foo: int
    bar: str


obj = OuterClass(InnerClass(foo=1, bar="some string"))

# 1-- dataclasses.asdict
asdict(obj)
# {'inner': {'foo': 1, 'bar': 'some string'}}

# 2-- json.dumps with `default`. Note that result is a string!
json.dumps(obj, default=lambda o: o.__dict__)
# {"inner": {"foo": 1, "bar": "some string"}}
  • Related