admin管理员组文章数量:1296293
I have a couple of classes instantiate basic types like str, int, float, list, dict's but also other classes that contains similar types. Essentially I have nested layers of objects. It is converted this way so data can be represented as objects and manipulated later. Once all the processing is done I want to export the data into a dictionary so it can be stored as a Json object on a database. Is this common? Are there libraries that help you do this.
So far I was going to implement a function that converts the top level class and nested objects into dictionary nested output. I'm worried I will get stack overflow from the recursion I will be using to
def getObjectAsDict(self):
d = {}
for name_of_attr in dir(some_class):
if name_of_attr.startswith("_"):
continue
value_of_attr = getattr(some_class, name_of_attr)
if isinstance(value_of_attr, str):
pass
elif isinstance(value_of_attr, int):
pass
elif isinstance(value_of_attr, float):
pass
elif isinstance(value_of_attr, bool):
pass
elif isinstance(value_of_attr, list):
for idx, item in enumerate(value_of_attr):
# some recursion logic here
elif isinstance(value_of_attr, dict):
for key, value in value_of_attr.items():
# some recursion logic here
elif isinstance(value_of_attr, ComplexObject):
value_of_attr = value_of_attr.getObjectAsDict()
# some recursion logic here
else:
continue
d[name_of_attr] = value_of_attr
I have a couple of classes instantiate basic types like str, int, float, list, dict's but also other classes that contains similar types. Essentially I have nested layers of objects. It is converted this way so data can be represented as objects and manipulated later. Once all the processing is done I want to export the data into a dictionary so it can be stored as a Json object on a database. Is this common? Are there libraries that help you do this.
So far I was going to implement a function that converts the top level class and nested objects into dictionary nested output. I'm worried I will get stack overflow from the recursion I will be using to
def getObjectAsDict(self):
d = {}
for name_of_attr in dir(some_class):
if name_of_attr.startswith("_"):
continue
value_of_attr = getattr(some_class, name_of_attr)
if isinstance(value_of_attr, str):
pass
elif isinstance(value_of_attr, int):
pass
elif isinstance(value_of_attr, float):
pass
elif isinstance(value_of_attr, bool):
pass
elif isinstance(value_of_attr, list):
for idx, item in enumerate(value_of_attr):
# some recursion logic here
elif isinstance(value_of_attr, dict):
for key, value in value_of_attr.items():
# some recursion logic here
elif isinstance(value_of_attr, ComplexObject):
value_of_attr = value_of_attr.getObjectAsDict()
# some recursion logic here
else:
continue
d[name_of_attr] = value_of_attr
Share
Improve this question
edited Feb 12 at 18:56
tyleax
asked Feb 12 at 4:43
tyleaxtyleax
1,7883 gold badges22 silver badges51 bronze badges
1
|
2 Answers
Reset to default 0The Python JSON Library allows you to pass in custom logic to handle serializing custom objects.
For example, if you have two classes, Foo
and Bar
with Foo
instances referencing Bar
instances:
class Foo:
def __init__(self, bar, x):
self.bar = bar
self.x = x
class Bar:
def __init__(self, y):
self.y = y
You can create a function that tells the JSON library how you want Foo
and Bar
objects to be turned into JSON serializable data — any time the JSON library comes across an object that it doesn't know how into JSON, it passes it to this function:
def foobar_serializer(obj):
if isinstance(obj, Foo):
return {"type": "Foo", "bar": obj.bar, "x": obj.x}
elif isinstance(obj, Bar):
return {"type": "Bar", "y": obj.y}
raise TypeError(f'Cannot serialize object of {type(obj)}')
You then pass this handler into the JSON dump/dumps function:
import json
my_foo = Foo(Bar(1), 2)
result = json.dumps(my_foo, default=foobar_serializer)
print(result) # {"type": "Foo", "bar": {"type": "Bar", "y": 1}, "x": 2}
Note that when foobar_serializer
is handling objects of type Foo
, it doesn't need to also handle objects of type Bar
— when the JSON dump/dumps function gets to bar
it will call the function again.
You can use custom encoder.
Example from documentation
import json
class ComplexEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, complex):
return [obj.real, obj.imag]
# Let the base class default method raise the TypeError
return super().default(obj)
json.dumps(2 + 1j, cls=ComplexEncoder)
ComplexEncoder().encode(2 + 1j)
list(ComplexEncoder().iterencode(2 + 1j))
Example for nested objects
from __future__ import annotations
class Foo:
def __init__(self, name: str, children: list[Foo] = None):
self.name = name
self.children = children or []
name: str
children: list[Foo]
def serialize(self):
return {"name": self.name, "children": self.children}
example_child_1 = Foo("example_child_1", [])
example_child_2 = Foo("example_child_2", [])
example = Foo("example", [example_child_1, example_child_2])
import json
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Foo):
return obj.serialize()
# Let the base class default method raise the TypeError
return super().default(obj)
json.dumps(example, cls=CustomEncoder)
本文标签: Python How to convert complex nested classes into dictionaryStack Overflow
版权声明:本文标题:Python How to convert complex nested classes into dictionary - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741620720a2388792.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
json.dumps(my_object, default=lambda o: o.__dict__ )
– JonSG Commented Feb 12 at 17:47