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"}}