1

在 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']

我更喜欢第二种选择,但我想知道是否有正确的方法。

谢谢。

4

3 回答 3

1

你现在只需要第一个 2 个字段。直到你真的需要更多。IMO 使用 Dataclass 的 _ _init _ _() 方法来处理它会更容易。否则,您将不得不同时更改函数调用 (MyDataClass(name=.....)) 和数据类 init。使用第二个选项,您只有一个需要干预的地方。

除非不关心/不需要是巨大的,并且您因此而受到性能打击......过早的优化是万恶之源。因此,尽可能保持简单和灵活!

于 2019-07-28T13:42:43.797 回答
1

假设将来,您想在选项 1 中从 中提取更多数据response并将其存储Dataclass:您需要增加__init__方法的参数以及您初始化的所有位置Dataclass。因此,选项 2 更可取,因为它减少了代码冗余并将数据提取逻辑保持在一个位置。

于 2019-07-28T13:52:06.923 回答
0

您绝对应该尽量避免覆盖数据类的__init__函数。有相当多的魔法,你会因为覆盖它而失去。除其他外,您将无法进行正确的__post_init__函数调用,除非您自己重写它。这不是微不足道的。

以这种方式工作的原因dataclass是因为它应该是您的业务数据到程序结构的非常简单的一对一映射。因此,您添加的每一种与该核心思想无关的附加逻辑都会削弱dataclass.

所以我建议坚持选项1。


如果手动写出想要的属性太麻烦了,你可以考虑编写一个类方法来过滤不需要的属性,并允许你像这样把字典弄脏:

dataclass_instance = MyDataClass.from_request(**resp)

是一篇解释如何做到这一点的帖子,随附的问题也涉及您的一些问题。

于 2019-08-02T09:47:36.183 回答