假设我有一些数据(可以是json
或dict
),它们以某种相对复杂的方式任意构造,如下面示例代码中的example
字典。
from dataclasses import asdict, dataclass, field
from typing import Any, List
@dataclass
class NameValue:
name: str
value: Any
@dataclass
class Category:
filters: List[NameValue] = field(default_factory=list)
description: Any = field(default=None)
@dataclass
class Container:
id: int
categories: List[Category] = field(default_factory=list)
def __post_init__(self):
if self.categories:
self.categories = [Category(**category) for category in self.categories]
def do_stuff(self, arg: str) -> None:
"""Do stuff with arg."""
print(f"Doing stuff with {arg}")
return None
def main():
example = {
"id": 1,
"categories": [
{
"filters": [
{"name": "two", "value": 2},
{"name": "three", "value": 3},
{"name": "four", "value": 4},
],
"description": "Kick it!",
},
{
"filters": [
{"name": "five", "value": 5},
{"name": "six", "value": 6},
{"name": "seven", "value": 7},
{"name": "eight", "value": 8},
],
"description": "Something to appreciate.",
},
],
}
container = Container(**example)
container.do_stuff("this thing")
assert asdict(container) == example
return None
if __name__ == "__main__":
main()
我希望能够轻松地处理对象形式的数据,这样我就能获得oop的好处。
我的想法是通过将一个解压缩的字典传递给Container
类来生成一个对象,操作这些对象,然后根据需要将它们返回给dict
s和/或json
字符串。
脚本在这个例子中运行良好,但是考虑到我在使用这种方法时遇到的一些问题(性能慢、默认值混乱等),我总觉得可能有更好的(即更有效、更像Python的)方法来完成这个任务。
提前感谢您的任何有益建议。
1条答案
按热度按时间nue99wik1#
这类事情有时被称为“装箱”--用它来谷歌一个包,你可以找到一些库,可以做准备安装在Pypi上。
但是,您的方法中的“性能”不应该是一个太大的问题--但是一些库可能会保留底层数据结构,并延迟获取所请求的字段--如果您正在处理成千上万个这样的对象,而当它们是Python对象时,实际上只使用了一小部分字段,那么这可能会产生影响--否则就不会了:为了检索Dict中的所有字段,其内容无论如何都必须被复制。
另外,如果你不想使用第三方库,那么用Python编写一些递归代码,将JSON解析成任意对象,这在某种程度上是很容易做到的--下面的代码就可以工作。如果你想解析成特定的预定义类,或者从Python文件中的预定义类解析出来,你必须采用这里介绍的手动方法。
这将适用于任意JSON结构,而无需在Python中声明任何类:
下面是示例数据如何在交互式环境中与此类一起工作: