在Python中,
我正在使用一个名为“ MyDataClass”的数据类来存储http响应返回的数据。假设响应内容是这样的json,并且我只需要前两个字段:
{
"name": "Test1",
"duration": 4321,
"dont_care": "some_data",
"dont_need": "some_more_data"
}
现在我有两个选择:
选项1
resp: dict = The response's content as json
my_data_class: MyDataClass(name=resp['name'], duration=resp['duration'])
我利用数据类的自动定义的 init 方法
或
选项2
resp: dict = The response's content as json
my_data_class: MyDataClass(resp)
并将处理留给数据类 init 方法,如下所示:
def _ _ init _ _(self, resp: Response) -> None:
self.name: str = resp['name']
self.duration: int = resp['duration']
我更喜欢第二个选项,但是我想知道是否有正确的方法。
谢谢。
答案 0 :(得分:1)
您现在仅需要前2个字段 。直到您最终需要更多。 IMO可以更轻松地使用Dataclass的_ _init _ _()方法来解决此问题。否则,您将必须同时更改函数调用(MyDataClass(name = .....))和数据类init。使用第二个选项,您只有一个地方需要干预。
除非不在乎/不需要是巨大的,否则您将因此而受到性能影响……过早的优化是万恶之源。因此,请尽可能保持其简单和灵活!
答案 1 :(得分:1)
让我们说,将来,您想从response
中提取更多数据并将其存储在Dataclass
中,在选项1中:您还需要增加__init__
方法的参数作为初始化Dataclass
的所有位置。因此,OPTION 2是可取的,因为它可以减少代码冗余并将数据提取逻辑保持在一个地方。
答案 2 :(得分:0)
您绝对应该避免覆盖数据类的__init__
函数。有quite a bit of magic只不过会因覆盖而丢失。除其他事项外,除非您自己进行重写,否则将无法进行正确的__post_init__
函数调用。这不是小事。
dataclass
如此工作的原因是,它应该是将业务数据非常简单地一对一映射到程序结构中。结果,您添加的每种与该核心思想无关的附加逻辑都失去了dataclass
的作用。
所以我建议坚持选择1。
如果手动写出所需的属性太麻烦了,您可以考虑编写一个类方法,该方法为您过滤掉不需要的属性,并允许您像这样喷洒字典:
dataclass_instance = MyDataClass.from_request(**resp)
Here是一则帖子,解释了如何做到这一点,伴随的问题也涉及您的某些问题。